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

2023-11-26

在PHP脚本中,是否调用include(), require(), fopen(),或它们的衍生物,例如include_once, require_once, 甚至,move_uploaded_file(),人们经常遇到错误或警告:

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

有什么好的流程可以快速找到问题的根本原因?


可能会遇到此错误的原因有很多,因此首先检查哪些内容的良好清单会很有帮助。

让我们假设我们正在对以下行进行故障排除:

require "/path/to/file"


清单


1.检查文件路径是否有拼写错误

  • 手动检查(通过目视检查路径)
  • 或移动任何被调用的东西require* or include*到它自己的变量,回显它,复制它,然后尝试从终​​端访问它:

    $path = "/path/to/file";
    
    echo "Path : $path";
    
    require "$path";
    

    然后,在终端中:

    cat <file path pasted>
    


2. 关于相对路径与绝对路径注意事项,检查文件路径是否正确

  • if it is starting by a forward slash "/" then it is not referring to the root of your website's folder (the document root), but to the root of your server.
    • 例如,您网站的目录可能是/users/tony/htdocs
  • if it is not starting by a forward slash then it is either relying on the include path (see below) or the path is relative. If it is relative, then PHP will calculate relatively to the path of the current working directory.
    • 因此,与网站根目录的路径或您正在键入的文件的路径无关
    • 因此,请始终使用绝对文件路径

最佳实践:

为了使您的脚本在移动内容时保持健壮,同时仍然在运行时生成绝对路径,您有 2 个选项:

  1. use require __DIR__ . "/relative/path/from/current/file". The __DIR__魔法常数返回当前文件的目录。
  2. 定义一个SITE_ROOT不变的自己:

    • 在网站目录的根目录中,创建一个文件,例如config.php
    • in config.php, write

      define('SITE_ROOT', __DIR__);
      
    • 在要引用站点根文件夹的每个文件中,包括config.php,然后使用SITE_ROOT无论你喜欢什么地方都保持不变:

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

这两种做法还使您的应用程序更加可移植,因为它不依赖于 ini 设置(例如包含路径)。


3.检查你的包含路径

另一种包含文件的方法(既不是相对也不是纯粹绝对)是依赖于包含路径。对于诸如 Zend 框架之类的库或框架来说,通常就是这种情况。

这样的包含将如下所示:

include "Zend/Mail/Protocol/Imap.php"

在这种情况下,您需要确保“Zend”所在的文件夹是包含路径的一部分。

您可以使用以下命令检查包含路径:

echo get_include_path();

您可以使用以下命令向其中添加文件夹:

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


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

总而言之,运行服务器进程(Apache 或 PHP)的用户可能根本没有读取或写入该文件的权限。

要检查服务器正在哪个用户下运行,您可以使用posix_getpwuid :

$user = posix_getpwuid(posix_geteuid());

var_dump($user);

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

ls -l <path/to/file>

看看权限符号表示法


5.检查PHP设置

如果上述方法均不起作用,则问题可能是某些 PHP 设置禁止它访问该文件。

三个设置可能相关:

  1. open_basedir
    • 如果设置了此选项,PHP 将无法访问指定目录之外的任何文件(甚至无法通过符号链接访问)。
    • 但是,默认行为是不设置,在这种情况下没有限制
    • 这可以通过调用来检查phpinfo()或通过使用ini_get("open_basedir")
    • 您可以通过编辑 php.ini 文件或 httpd.conf 文件来更改设置
  2. safe mode
    • 如果打开此功能,可能会受到限制。然而,这在 PHP 5.4 中已被删除。如果您仍在使用支持安全模式的版本,请升级到 PHP 版本仍在支持中.
  3. allow_url_fopen and allow_url_include
    • 这仅适用于通过网络进程(例如 http://)包含或打开文件,不适用于尝试包含本地文件系统上的文件
    • 这可以通过检查ini_get("allow_url_include")并设置为ini_set("allow_url_include", "1")


极端情况

如果上述方法均无法诊断问题,则可能会发生以下一些特殊情况:


1.依赖include路径的库的包含

您可能会使用相对或绝对路径包含一个库,例如 Zend 框架。例如 :

require "/usr/share/php/libzend-framework-php/Zend/Mail/Protocol/Imap.php"

但你仍然会遇到同样的错误。

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

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

include "Zend/Mail/Protocol/Exception.php" 

它既不是通过相对路径包含,也不是通过绝对路径包含。假设 Zend 框架目录已添加到包含路径中。

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


2.SELinux

如果您运行的是安全增强型 Linux,则拒绝从服务器访问该文件可能是导致问题的原因。

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

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

setenforce 0

如果关闭 SELinux 后不再出现问题,那么这就是根本原因。

为了解决它,您必须相应地配置 SELinux。

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

  • httpd_sys_content_t对于您希望服务器能够读取的文件
  • httpd_sys_rw_content_t对于您想要读写访问权限的文件
  • httpd_log_t对于日志文件
  • httpd_cache_t对于缓存目录

例如,要分配httpd_sys_content_tcontext 类型到您的网站根目录,运行:

semanage fcontext -a -t httpd_sys_content_t "/path/to/root(/.*)?"
restorecon -Rv /path/to/root

如果您的文件位于主目录中,您还需要打开httpd_enable_homedirs布尔值:

setsebool -P httpd_enable_homedirs 1

无论如何,SELinux 拒绝访问文件的原因可能有多种,具体取决于您的策略。所以你需要对此进行调查。Here是专门为 Web 服务器配置 SELinux 的教程。


3. 交响乐

如果您使用 Symfony,并且在上传到服务器时遇到此错误,则可能是应用程序的缓存尚未重置,因为app/cache已上传,或者缓存尚未清除。

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

cache:clear


4. Zip 文件中的非 ASCII 字符

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

一个可能的解决方案是将文件名包装在utf8_decode()在创建目标文件之前。

致谢弗兰卡诺用于确定此问题并提出解决方案

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 无法与站点通信以检查致命错误

    无法与站点通信以检查致命错误 因此 PHP 更改已恢复 您需要通过其他方式上传 PHP 文件更改 例如使用 SFTP 有什么解决办法 我正在 WordPress 中编辑头文件 遇到这个问题 尝试这个 我有同样的问题并决定调查一下 更改 wp
  • 将字符串的第一个字母大写(前面带有特殊字符) - PHP

    我想将字符串大写 例如 hello 我希望我的函数返回 Hello 我尝试过使用 regex 和 preg match 但没有运气 这是我之前的问题 与此相关 preg match 正在匹配两个字符 而它应该只匹配一个字符 https st
  • file_get_contents,HTTP 请求失败

    我尝试使用以下方式从另一个网站获取内容file get contents但我总是收到 无法打开流 HTTP 请求失败 allow url fopen 已打开 并且我已经在防火墙关闭的情况下进行了测试 但还是会出现这种情况 请问还有什么原因呢
  • 如何将对象(模型类型对象)插入到 Laravel 中 Collection 对象的特定索引号处?

    我读过戴尔 里斯的代码明亮 https daylerees com codebright 了解更多关于雄辩的信息Collection在 Laravel 中使用 还做了一些其他研究 但找不到我正在寻找的答案 我想插入一个对象 Model输入对
  • 从 Symfony2 中的 http_basic auth 注销

    每当我去 admin logout 我已正确重定向到项目的根目录 但在访问时仍处于登录状态 admin 因为没有提示我输入凭据 这是我的配置 安全 yml security firewalls admin area pattern admi
  • PHP 自定义会话处理程序问题 (PHP 7.1)

    我刚刚在计算机上从 PHP 7 0 迁移到 PHP 7 1 当前版本的 WAMP 的全新 全新安装 它似乎破坏了自定义会话处理程序中的某些内容 该处理程序应该将会话保存到数据库而不是使用文件系统 自定义处理程序类是 class db ses
  • Laravel 5 配置语言环境,不起作用

    已完成的修改 on 配置 应用程序 php locale gt env APP LOCALE en fallback locale gt en on env APP LOCALE pt 我也复制了 资源 lang en文件到 资源 lang
  • 这是过滤数据并防止 SQL 注入和其他攻击的安全方法吗?

    我创建了两个简单的函数来在插入数据进入 mysql 查询之前对其进行过滤 对于表单字段 我还使用正则表达式来单独检查每个字段 Form filter function filter var HTML is not allowed var s
  • CodeIgniter/PHP - 从视图内调用视图

    基本上 对于我的网络应用程序 我正在尝试更好地组织它 目前 每次我想加载页面时 我都必须从控制器中执行此操作 如下所示 this gt load gt view subviews template headerview this gt lo
  • 我们可以在 Bash 脚本中使用 PHP 吗?

    我有一个 bash 脚本abcd sh bin sh for i in seq 8 do ssh w i uptime ps elf grep httpd wc l free m mpstat done pid sleep 1 kill 9
  • 使用 CodeIgniter 加载视图文件夹外的视图

    我需要从以下范围之外加载视图 this gt load gt view 这似乎是从base application views目录 如何从外部访问视图 application 目录 我想我将不得不延长CI Loader class这是最好的
  • Zend 框架会话丢失

    我有一个注册表单 当用户注册时 它会将他重定向到他的页面 在 Firefox 和 Chrome 中一切正常 但在 Internet Explorer 中则正常 看起来保存用户信息后 会话就关闭了 并且不会将用户重定向到他的页面 我该如何解决
  • 与 PHP 相比,Python 与 HTML 的“流畅”程度如何?

    我正在考虑从使用 PHP 切换到使用 Python 来开发 Web 应用程序 但我想知道 Python 是否像 PHP 一样擅长在 HTML 中穿插 本质上 我发现它使用起来非常简单 直观将 PHP 放在我想要的位置 然后可以随意安排 组织
  • PHP 中正确的存储库模式设计?

    前言 我尝试在具有关系数据库的 MVC 架构中使用存储库模式 我最近开始学习 PHP 中的 TDD 并且我意识到我的数据库与应用程序的其余部分耦合得太紧密 我读过有关存储库并使用国际奥委会容器 http laravel com docs 4
  • 什么是 PHP session_start()

    它是否基于 cookie 启动当前会话 从 PHP 网站上得到的 PHP如何控制会话 如果我在用户打开我的登录页面时启动会话 我什至可以使用该会话做什么 我可以使用当前会话来获取有关登录用户的信息吗 PHP 会话系统允许您将数据安全地存储在
  • 如何让php页面从html页面接收ajax post

    我有一个非常简单的表单 其中有一个名字输入字段 我捕获了表单数据 并使用标准 jQuery 发布方法通过 ajax 将其传输到 PHP 页面 但是 我根本无法从 PHP 页面获得任何在服务器端捕获数据的响应 我不确定我做错了什么或缺少什么
  • 访问 PHP 数组对象受保护的属性

    我正在尝试在 Symfony2 中上传多个文件 我正在尝试访问以下请求对象 但无法获取参数属性 如何将文件一一上传 我得到的错误 致命错误 无法访问第 66 行 var www File src Webmuch FileBundle Ent
  • 单元测试和静态方法

    阅读并学习单元测试 试图理解以下帖子 http misko hevery com 2008 12 15 static methods are death to testability 这解释了静态函数调用的困难 我不太清楚这个问题 我一直认
  • 突出显示单词并提取其附近文本的函数

    我有一个文本例如 Etiam porta semmalesuada magna mollis euismod 整数取数 ante venenatis dapibus posuere velit aliquet 埃蒂亚姆 门塔 塞姆 male
  • jQuery appendTo(), json 在 IE 6,7,8 中不起作用

    我这两天绞尽脑汁想找到解决办法 我使用 jQuery ajax 从数据库中获取值 以便在另一个框发生更改时更新一个框 php 脚本从数据库中获取值 然后输出 json 它在 FF 中工作正常 但在所有版本的 IE 中 选择框都不会更新 我已

随机推荐