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

By simon at 2018-02-28 • 0人收藏 • 73人看过

在PHP脚本中,无论是拨打include(),require(),fopen()还是 其衍生物如include_once,9require_once,甚至move_uploaded_file(), 经常遇到错误或警告:

无法打开流:没有这样的文件或目录。 什么是一个很好的过程,可以快速找到问题的根源?

4 个回复 | 最后更新于 2018-02-28
2018-02-28   #1

有很多原因可能会遇到这个错误,因此是一件好事 首先检查什么清单可以帮助很大。 乐t认为我们正在解决以下问题:

require "/path/to/file"
#清单

1 \。检查文件路径是否有错别字

  * ei请手动检查(通过目视检查路径)   *或将require*或include*所称的任何东西移动到其自己的位置变量,回显,复制,并尝试从终端访问它:

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

echo "Path : $path";

require "$path";
然后,在终端中:
cat <file path pasted>

2 \。检查一下在文件路径上是相对于绝对路径是正确的

注意事项   如果它是以正斜杠“/”开始的话它不是指您的网站文件夹(文档根目录)的根目录,而是指您的服务器的根目录。     例如e,您网站的目录可能是/users/tony/htdocs   如果它不是以正斜杠开始,那么它要么依赖于包括路径(见下文)或路径是相对的。如果它是相对的,那么PHP将相对于[cur]的路径进行计算租工作目录](https://secure.php.net/manual/en/function.getcwd.php)。     因此,不相对于你的w路径ebsite的根目录或您正在输入的文件     出于这个原因,总是使用绝对文件路径 最佳实践: 在ord中呃让你的脚本在你移动的时候保持健壮,同时 仍然在运行时生成绝对路径,你有2选择离子:   1.使用require __DIR__ . "/relative/path/from/current/file". [__DIR__魔术常数](https://secure.php.net/manual/en/language.constants.predefined.php)返回当前文件的目录。   2.自己定义一个SITE_ROOT常量:     在你的网站的根源网站的目录,创建一个文件,例如config.php     在config.php,写

define('SITE_ROOT', __DIR__);
    在你w的每个文件中ant引用站点根文件夹,包括
cat <file path pasted>
17,然后在任何你喜欢的地方使用SITE_ROOT常量:
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
这两种做法也使您的应用程序更具可移植性,因为它没有 依赖ini设置,如include pa日。

3 \。检查你的包含路径

包含文件的另一种方式是,既不相对也不纯粹 依靠[in包括路径](https://secure.php.net/manual/en/ini.core.php#ini .INCLUDE路径)。图书馆或框架通常是这种情况如那个 Zend框架。 这样的包含将如下所示:

include "Zend/Mail/Protocol/Imap.php"
在这种情况下,你会想确保t他是“Zend”所在的文件夹 包含路径的一部分。 您可以通过以下方式检查包含路径:
echo get_include_path();
您可以添加一个文件夹与它:
set_include_path(get_include_path().":"."/path/to/new/folder");

4 \。检查您的服务器是否有权访问该文件

完全可能是用户在运行e服务器进程(Apache或 PHP)根本没有权限读取或写入该文件。 检查下用户服务器正在运行,您可以使用 [posixgetpwuid](https://secure.php.net/manual/en/function.posix-getpwuid.php) :

$user = posix_getpwuid(posix_geteuid());

var_dump($user);
至找出文件的权限,在文件中输入以下命令 终奌站: 9
require "/path/to/file"
并看看[权限符号符号(https://en.wikipedia.org/wiki/File
systempermissions#Symbolicnotation)

5 \。检查PHP设置

如果没有一个above工作,那么问题可能是一些PHP设置 禁止它访问该文件。 三个设置可能是相关的:1. [openbasedir](https://secure.php.net/manual/en/ini.core.php#ini.open-basedir)     *如果这是设置PHP将无法接受ss指定目录之外的任何文件(甚至不通过符号链接)。     *但是,默认行为是为了它在这种情况下不设置限制     *可以通过拨打[phpinfo()](https:// secure)来检查.php.net / manual / en / function.phpinfo.php)或使用ini_get("open_basedir")     *您可以通过编辑您的php来更改设置。ini文件或您的httpd.conf文件   2. [安全模式](https://secure.php.net/manual/en/features.safe-mode.php)     *如果这是转机编辑限制可能适用。但是,这在PHP 5.4中已被删除。如果您仍然使用支持安全模式的版本升级到[仍然支持]的PHP版本(http://php.net/eol.php)。   3. [allowurlfopen和allowurl_include](htTPS://secure.php.net/manual/en/filesystem.configuration.php)     这仅适用于通过网络包含或打开文件工作过程如http://不要试图在本地文件系统上包含文件     这可以用9999999999进行检查4419并设置ini_set("allow_url_include", "1") #角落案件 如果以上都不能诊断问题,这里有一些特别的 原位可能发生的事情:

1 \。包含依赖于包含路径的库

可能发生的情况是,您包括一个图书馆,例如丰富的Zend框架, 使用相对或绝对路径。例如 :

require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
但是,你仍然会得到同样的东西错误。 这可能会发生,因为您已经(成功)包含的文件具有 本身就是另一个fil的包含声明e,第二个包括 声明假定您已将该库的路径添加到include 路径。 例如,前面提到的Zend框架文件可能具有以下内容 包括:
include "Zend/Mail/Protocol/Exception.php" 
这既不是亲属的包容路径,也不是绝对路径。它是 假设Zend框架目录已被添加到包含路径中。 在这种情况下,唯一可行的解​​决方案是将目录添加到您的 包括路径。

2 \。 SELinux的

如果您正在运行安全增强型LLinux,那么它可能是原因 该问题通过拒绝从服务器访问文件来实现。 检查SELinux是否启用,运行sestatus 命令在终端中。如果该命令不存在,那么SELinux未打开 哟你的系统。如果它确实存在,那么它应该告诉你它是否被强制执行 或不。 要检查SELinux策略是否是原因的问题,你可以 尝试暂时关闭它。不过要小心,因为这会失效 保护wholel年。不要在生产服务器上执行此操作。

setenforce 0
如果你不再有SELinux关闭的问题,那么这个是个 根本原因。 要解决它,您必须相应地配置SELinux。 以下上下文类型将是必需的ry:   * httpd_sys_content_t用于希望服务器能够读取的文件   * httpd_sys_rw_content_t用于您想要的文件广告和写入权限   * httpd_log_t用于日志文件   * httpd_log_t用于缓存目录 例如,分配httpd_sys_content_t上下文类型到您的网站根目录 目录,运行:
semanage fcontext -a -t http_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
如果您的文件位于主目录中,您也将不在编辑打开 httpd_enable_homedirs布尔值:
setsebool -P httpd_enable_homedirs 1
无论如何,SELinux会否认会有各种各样的原因访问 到一个文件,这取决于你的政策。所以你需要对此进行调查。 [这里](http://www.serverlab.ca/tutorials/lLINUX /网络服务器Linux的/ configuring- selinux-policies-for-apache-web-servers /)是一个特别的教程 配置SELinux为Web服务器。

3 \。 Symfony的

如果您正在使用Symfony,并且在上传到某个文件时遇到此错误 服务器,那么它可以be应用程序的缓存尚未重置,因为 app/cache已上载,或者该缓存尚未清除。 哟您可以通过运行以下控制台命令来测试并解决此问题:

cache:clear

4 \。 Zip文件中的非ACSII字符

APPA肯定这个错误也可能发生在一些时候调用zip->close() zip内的文件在其中包含非ASCII字符文件名,如 “é”。 潜在的解决方案是在之前将文件名包装在utf8_decode()中 创建目标文件。 信用s到[Fran Cano](https://stackoverflow.com/users/4217158/fran-cano) 确定并建议解决这个问题

2018-02-28   #2

有很多原因可能会遇到这个错误,因此是一件好事 首先检查什么清单可以帮助很大。 乐t认为我们正在解决以下问题:

require "/path/to/file"
#清单

1 \。检查文件路径是否有错别字

  * ei请手动检查(通过目视检查路径)   *或将require*或include*所称的任何东西移动到其自己的位置变量,回显,复制,并尝试从终端访问它:

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

echo "Path : $path";

require "$path";
然后,在终端中:
cat <file path pasted>

2 \。检查一下在文件路径上是相对于绝对路径是正确的

注意事项   如果它是以正斜杠“/”开始的话它不是指您的网站文件夹(文档根目录)的根目录,而是指您的服务器的根目录。     例如e,您网站的目录可能是/users/tony/htdocs   如果它不是以正斜杠开始,那么它要么依赖于包括路径(见下文)或路径是相对的。如果它是相对的,那么PHP将相对于[cur]的路径进行计算租工作目录](https://secure.php.net/manual/en/function.getcwd.php)。     因此,不相对于你的w路径ebsite的根目录或您正在输入的文件     出于这个原因,总是使用绝对文件路径 最佳实践: 在ord中呃让你的脚本在你移动的时候保持健壮,同时 仍然在运行时生成绝对路径,你有2选择离子:   1.使用require __DIR__ . "/relative/path/from/current/file". [__DIR__魔术常数](https://secure.php.net/manual/en/language.constants.predefined.php)返回当前文件的目录。   2.自己定义一个SITE_ROOT常量:     在你的网站的根源网站的目录,创建一个文件,例如config.php     在config.php,写

define('SITE_ROOT', __DIR__);
    在你w的每个文件中ant引用站点根文件夹,包括
cat <file path pasted>
17,然后在任何你喜欢的地方使用SITE_ROOT常量:
require_once __DIR__."/../config.php";
...
require_once SITE_ROOT."/other/file.php";
这两种做法也使您的应用程序更具可移植性,因为它没有 依赖ini设置,如include pa日。

3 \。检查你的包含路径

包含文件的另一种方式是,既不相对也不纯粹 依靠[in包括路径](https://secure.php.net/manual/en/ini.core.php#ini .INCLUDE路径)。图书馆或框架通常是这种情况如那个 Zend框架。 这样的包含将如下所示:

include "Zend/Mail/Protocol/Imap.php"
在这种情况下,你会想确保t他是“Zend”所在的文件夹 包含路径的一部分。 您可以通过以下方式检查包含路径:
echo get_include_path();
您可以添加一个文件夹与它:
set_include_path(get_include_path().":"."/path/to/new/folder");

4 \。检查您的服务器是否有权访问该文件

完全可能是用户在运行e服务器进程(Apache或 PHP)根本没有权限读取或写入该文件。 检查下用户服务器正在运行,您可以使用 [posixgetpwuid](https://secure.php.net/manual/en/function.posix-getpwuid.php) :

$user = posix_getpwuid(posix_geteuid());

var_dump($user);
至找出文件的权限,在文件中输入以下命令 终奌站: 9
require "/path/to/file"
并看看[权限符号符号(https://en.wikipedia.org/wiki/File
systempermissions#Symbolicnotation)

5 \。检查PHP设置

如果没有一个above工作,那么问题可能是一些PHP设置 禁止它访问该文件。 三个设置可能是相关的:1. [openbasedir](https://secure.php.net/manual/en/ini.core.php#ini.open-basedir)     *如果这是设置PHP将无法接受ss指定目录之外的任何文件(甚至不通过符号链接)。     *但是,默认行为是为了它在这种情况下不设置限制     *可以通过拨打[phpinfo()](https:// secure)来检查.php.net / manual / en / function.phpinfo.php)或使用ini_get("open_basedir")     *您可以通过编辑您的php来更改设置。ini文件或您的httpd.conf文件   2. [安全模式](https://secure.php.net/manual/en/features.safe-mode.php)     *如果这是转机编辑限制可能适用。但是,这在PHP 5.4中已被删除。如果您仍然使用支持安全模式的版本升级到[仍然支持]的PHP版本(http://php.net/eol.php)。   3. [allowurlfopen和allowurl_include](htTPS://secure.php.net/manual/en/filesystem.configuration.php)     这仅适用于通过网络包含或打开文件工作过程如http://不要试图在本地文件系统上包含文件     这可以用9999999999进行检查4419并设置ini_set("allow_url_include", "1") #角落案件 如果以上都不能诊断问题,这里有一些特别的 原位可能发生的事情:

1 \。包含依赖于包含路径的库

可能发生的情况是,您包括一个图书馆,例如丰富的Zend框架, 使用相对或绝对路径。例如 :

require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"
但是,你仍然会得到同样的东西错误。 这可能会发生,因为您已经(成功)包含的文件具有 本身就是另一个fil的包含声明e,第二个包括 声明假定您已将该库的路径添加到include 路径。 例如,前面提到的Zend框架文件可能具有以下内容 包括:
include "Zend/Mail/Protocol/Exception.php" 
这既不是亲属的包容路径,也不是绝对路径。它是 假设Zend框架目录已被添加到包含路径中。 在这种情况下,唯一可行的解​​决方案是将目录添加到您的 包括路径。

2 \。 SELinux的

如果您正在运行安全增强型LLinux,那么它可能是原因 该问题通过拒绝从服务器访问文件来实现。 检查SELinux是否启用,运行sestatus 命令在终端中。如果该命令不存在,那么SELinux未打开 哟你的系统。如果它确实存在,那么它应该告诉你它是否被强制执行 或不。 要检查SELinux策略是否是原因的问题,你可以 尝试暂时关闭它。不过要小心,因为这会失效 保护wholel年。不要在生产服务器上执行此操作。

setenforce 0
如果你不再有SELinux关闭的问题,那么这个是个 根本原因。 要解决它,您必须相应地配置SELinux。 以下上下文类型将是必需的ry:   * httpd_sys_content_t用于希望服务器能够读取的文件   * httpd_sys_rw_content_t用于您想要的文件广告和写入权限   * httpd_log_t用于日志文件   * httpd_log_t用于缓存目录 例如,分配httpd_sys_content_t上下文类型到您的网站根目录 目录,运行:
semanage fcontext -a -t http_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root
如果您的文件位于主目录中,您也将不在编辑打开 httpd_enable_homedirs布尔值:
setsebool -P httpd_enable_homedirs 1
无论如何,SELinux会否认会有各种各样的原因访问 到一个文件,这取决于你的政策。所以你需要对此进行调查。 [这里](http://www.serverlab.ca/tutorials/lLINUX /网络服务器Linux的/ configuring- selinux-policies-for-apache-web-servers /)是一个特别的教程 配置SELinux为Web服务器。

3 \。 Symfony的

如果您正在使用Symfony,并且在上传到某个文件时遇到此错误 服务器,那么它可以be应用程序的缓存尚未重置,因为 app/cache已上载,或者该缓存尚未清除。 哟您可以通过运行以下控制台命令来测试并解决此问题:

cache:clear

4 \。 Zip文件中的非ACSII字符

APPA肯定这个错误也可能发生在一些时候调用zip->close() zip内的文件在其中包含非ASCII字符文件名,如 “é”。 潜在的解决方案是在之前将文件名包装在utf8_decode()中 创建目标文件。 信用s到[Fran Cano](https://stackoverflow.com/users/4217158/fran-cano) 确定并建议解决这个问题

2018-02-28   #3

添加到(真的很好)现有的答案 #共享主机软件 open_basedir是一个可以让你陷害的因为它可以是s的在网络中指定 服务器配置。虽然如果你自己运行,这很容易解决 专用服务器,有一些共享d在那里托管软件包 (如Plesk,cPanel等),它们将在一个配置指令上进行配置 per-domain baSIS。由于软件构建了配置文件(即 httpd.conf)你不能直接更改该文件,因为ho刺 软件将在重新启动时覆盖它。 使用Plesk,他们提供了一个覆盖提供的httpd.conf的地方叫 vhost.conf.只有服务器管理员可以写入该文件。配置 对于Apache看起来像这样

<Directory /var/www/vhosts/domain.com>
    <IfModule mod_php5.c>
        php_admin_flag engine on
        php_admin_flag safe_mode off
        php_admin_value open_basedir "/var/www/vhosts/domain.com:/tmp:/usr/share/pear:/local/PEAR"
    </IfModule>
</Directory>
让您的服务器管理员查阅托管和Web服务器的手册 他们使用的软件。 #文件权限 这是重要的请注意,通过您的Web服务器执行文件非常重要 与命令行或cron作业执行不同。巨大的差异ference是 您的Web服务器拥有自己的用户和权限。出于安全原因 该用户相当受限制。 Apache,f或实例,通常是apache, www-data或httpd(取决于您的服务器)。一个cron作业或CLI 执行哈s运行它的用户拥有的任何权限(即运行) 作为root的PHP脚本将以root权限执行)。 一个很多时候人们会通过执行以下操作来解决权限问题 (Linux例子)
chmod 777 /path/to/file
这不是一个聪明的IDea,因为文件或目录现在是世界可写的。 如果你拥有服务器,并且是唯一的用户,那么这不是那么大这笔交易, 但是如果你在一个共享的主机环境中,你只是给了每个人 你的服务器访问。 你需要做的是det呃需要访问和给予的用户 他们访问。一旦你知道哪些用户需要访问,你会想要 小号那个   1.该用户拥有文件和可能的父目录(尤其是父目录,如果你想写e文件)。在大多数共享主机环境中,这不会成为问题,因为您的用户应该拥有您的所有文件根。一个Linux例子如下所示
chown apache:apache /path/to/file
  2.用户,并且只有该用户有权访问。在Linux中,一个很好的习惯would是chmod 600(只有车主可以读写)或chmod 644(车主可以写但是每个人都可以读) 你可以[读一个月重新讨论Linux / Unix权限和用户 这里](https://unix.stackexchange.com/questions/35711/giving-php-permi裂变-TO- 写入到文件和文件夹)

2018-02-28   #4

另一个可能的原因:在文本编辑器中重命名和/或移动文件。一世 经历了上述所有步骤都没有成功直到我删除了那个文件 不断抛出这个错误,并创建了一个新的问题,解决了这个问题。

登录后方可回帖

Loading...