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

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

什么是快速找到问题根源的良好流程?


当前回答

除了其他精彩的回答,在Windows上写一个简单的脚本时,我忽略了一件事:当试图打开一个带有Windows不支持的文件名字符的文件时,会出现这个错误。

例如:

$file = fopen(date('Y-m-d_H:i:s'), 'w+');

将:

fopen(2022-06-01_22:53:03): Failed to open stream: No such file or directory in…

Windows不喜欢:在文件名中,以及其他一些字符。

其他回答

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

例如,我会上传一张图片。但是我得到了这个错误。第一件事,我会做右键点击图像和获取信息。

$ thepathofmpicture = "/Users/misstugba/Desktop/"; 配合功能使用

if(move_uploaded_file($_FILES["file"]["tmp_name"],$thePathOfMyPicture.$_FILES["file"]["name"])){
echo "image uploaded successfully";

}

Samba股票

如果您有一个Linux测试服务器,并且从Windows客户端工作,那么Samba共享会干扰chmod命令。所以,即使你使用:

chmod -R 777 myfolder

在Linux方面,Unix组\www-data仍然没有写权限是完全可能的。如果您的共享设置为Windows管理员映射到根目录,一个可行的解决方案是:在Windows中,打开权限,禁用带有副本的文件夹的继承,然后授予www-data的完全访问权限。

下面的PHP设置在PHP .ini中如果设置为不存在的目录也会引发

PHP警告:未知:未能打开流:权限被拒绝 第0行未知

sys_temp_dir
upload_tmp_dir
session.save_path

添加带有查询参数的脚本

那是我的案子。它实际上链接到问题#4485874,但我将在这里简短地解释它。 当你试图要求路径/到/script.php?参数=值,PHP查找名为script.php的文件?parameter=value,因为UNIX允许您使用这样的路径。 如果你真的需要传递一些数据到包含的脚本,只需声明它为$variable=…或全局美元[]=…或者其他你喜欢的方式。

为现有的(非常好的)答案补充

共享托管软件

Open_basedir是一个让你为难的参数,因为它可以在web服务器配置中指定。虽然如果你运行自己的专用服务器,这很容易补救,但有一些共享托管软件包(如Plesk, cPanel等)会在每个域的基础上配置配置指令。因为软件构建了配置文件(即httpd.conf),所以你不能直接更改该文件,因为主机软件在重新启动时会覆盖它。

使用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服务器软件的手册。

文件权限

It's important to note that executing a file through your web server is very different from a command line or cron job execution. The big difference is that your web server has its own user and permissions. For security reasons that user is pretty restricted. Apache, for instance, is often apache, www-data or httpd (depending on your server). A cron job or CLI execution has whatever permissions that the user running it has (i.e. running a PHP script as root will execute with permissions of root).

很多时候人们会通过以下方法来解决权限问题(以Linux为例)

chmod 777 /path/to/file

这不是一个明智的想法,因为文件或目录现在是全局可写的。如果您拥有服务器,并且是唯一的用户,那么这不是什么大问题,但如果您在共享托管环境中,您只是给了服务器上的每个人访问权。

您需要做的是确定需要访问权限的用户,并只给他们访问权限。一旦你知道哪些用户需要访问,你就会想要确保这一点

该用户拥有文件,可能还拥有父目录(如果您想写入文件,则尤其拥有父目录)。在大多数共享主机环境中,这不是问题,因为您的用户应该拥有根目录下的所有文件。下面显示了一个Linux示例 Chown apache:apache /path/to/file 用户,且只有该用户具有访问权限。在Linux中,一个好的做法是chmod 600(只有所有者可以读写)或chmod 644(所有者可以写,但每个人都可以读)

你可以在这里阅读更多关于Linux/Unix权限和用户的讨论