PHP-无法打开流:没有这样的文件或目录

PHP-无法打开流:没有这样的文件或目录,php,require,fopen,include-path,Php,Require,Fopen,Include Path,在PHP脚本中,无论是调用include(),require(),fopen(),还是它们的衍生工具,如include\u once,require\u once,甚至是移动上传的文件(),都经常会遇到错误或警告: 无法打开流:没有这样的文件或目录 快速找到问题根本原因的好方法是什么?有很多原因可能会出现这种错误,因此,一个好的先检查什么的清单会有很大帮助 让我们考虑一下下面的行: require "/path/to/file" 清单 1.检查文件路径是否有打字错误 手动检查(通过目视检

在PHP脚本中,无论是调用
include()
require()
fopen()
,还是它们的衍生工具,如
include\u once
require\u once
,甚至是
移动上传的文件()
,都经常会遇到错误或警告:

无法打开流:没有这样的文件或目录


快速找到问题根本原因的好方法是什么?

有很多原因可能会出现这种错误,因此,一个好的先检查什么的清单会有很大帮助

让我们考虑一下下面的行:

require "/path/to/file"

清单

1.检查文件路径是否有打字错误
  • 手动检查(通过目视检查路径)
  • 或者将
    require*
    include*
    调用的任何内容移动到它自己的变量中,回显它,复制它,然后尝试从终端访问它:

    $path = "/path/to/file";
    
    echo "Path : $path";
    
    require "$path";
    
    cat <file path pasted>
    
    ls -l <path/to/file>
    
    然后,在终端中:

    $path = "/path/to/file";
    
    echo "Path : $path";
    
    require "$path";
    
    cat <file path pasted>
    
    ls -l <path/to/file>
    
  • 在要引用站点根文件夹的每个文件中,包括
    config.php
    ,然后在任何需要的地方使用
    site\u root
    常量:

    require_once __DIR__."/../config.php";
    ...
    require_once SITE_ROOT."/other/file.php";
    
这两种做法还使应用程序更具可移植性,因为它不依赖于ini设置,如include路径


3.检查您的包含路径 包含文件的另一种方式,既不是相对的,也不是绝对的,是依赖于。对于像Zend框架这样的库或框架来说,这种情况经常发生

这样的包含将如下所示:

include "Zend/Mail/Protocol/Imap.php"
在这种情况下,您需要确保“Zend”所在的文件夹是include路径的一部分

您可以使用以下选项检查包含路径:

echo get_include_path();
您可以通过以下方式向其中添加文件夹:

set_include_path(get_include_path().":"."/path/to/new/folder");

4.检查您的服务器是否有权访问该文件 这可能是因为,运行服务器进程(Apache或PHP)的用户根本没有读取或写入该文件的权限

要检查服务器运行的用户,可以使用:

要查找文件的权限,请在终端中键入以下命令:

$path = "/path/to/file";

echo "Path : $path";

require "$path";
cat <file path pasted>
ls -l <path/to/file>
但是你仍然会得到同样的错误

这可能是因为您(成功)包含的文件本身具有另一个文件的include语句,并且第二个include语句假定您已将该库的路径添加到include路径

例如,前面提到的Zend framework文件可能包含以下内容:

include "Zend/Mail/Protocol/Exception.php" 
它既不是相对路径的包含,也不是绝对路径的包含。假设Zend framework目录已添加到include路径

在这种情况下,唯一实用的解决方案是将目录添加到include路径


2.塞利努克斯 如果您运行的是增强安全性的Linux,那么这可能是问题的原因,因为您拒绝从服务器访问该文件

要检查系统上是否启用了SELinux,请在终端中运行
sestatus
命令。如果命令不存在,则系统上不存在SELinux。如果它确实存在,那么它应该告诉你它是否被强制执行

要检查SELinux策略是否是问题的原因,可以尝试暂时关闭它。但是要小心,因为这将完全禁用保护。不要在生产服务器上执行此操作

setenforce 0
如果您不再存在关闭SELinux的问题,那么这就是根本原因

要解决此问题,您必须相应地配置SELinux

以下上下文类型是必需的:

  • httpd\u sys\u content\t
    用于您希望服务器能够读取的文件
  • httpd\u sys\u rw\u content\u t
    用于您希望对其进行读写访问的文件
  • httpd\u log\t
    用于日志文件
  • 缓存目录的
    httpd\u cache\t
例如,要将
httpd\u sys\u content\u t
上下文类型分配给网站根目录,请运行:

semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
如果文件位于主目录中,则还需要启用
httpd\u enable\u homedirs
布尔值:

setsebool -P httpd_enable_homedirs 1
在任何情况下,SELinux拒绝访问文件可能有多种原因,具体取决于您的策略。所以你需要调查一下。本教程专门介绍如何为web服务器配置SELinux


3.西蒙尼 如果您正在使用Symfony,并且在上载到服务器时遇到此错误,则可能是由于
app/cache
已上载,或者该缓存尚未清除,应用的缓存尚未重置

您可以通过运行以下控制台命令来测试和修复此问题:

cache:clear

4.Zip文件中的非ACSII字符 显然,调用
zip->close()
时,如果zip中的某些文件的文件名中包含非ASCII字符,例如“é”,也会发生此错误

一个可能的解决方案是在创建目标文件之前,将文件名包装在
utf8\u decode()


确认并建议解决此问题的方法的功劳

一个人可能会遇到此错误的原因有很多,因此,一个好的先检查什么的清单会有很大帮助

让我们考虑一下下面的行:

require "/path/to/file"

清单

1.检查文件路径是否有打字错误
  • 手动检查(通过目视检查路径)
  • 或者将
    require*
    include*
    调用的任何内容移动到它自己的变量中,回显它,复制它,然后尝试从终端访问它:

    $path = "/path/to/file";
    
    echo "Path : $path";
    
    require "$path";
    
    cat <file path pasted>
    
    ls -l <path/to/file>
    
    然后,在终端中:

    $path = "/path/to/file";
    
    echo "Path : $path";
    
    require "$path";
    
    cat <file path pasted>
    
    ls -l <path/to/file>
    
  • 在要引用站点根文件夹的每个文件中,包括
    config.php
    ,然后在任何需要的地方使用
    site\u root
    常量:

    require_once __DIR__."/../config.php";
    ...
    require_once SITE_ROOT."/other/file.php";
    
泰斯