是的,另一个关于fopen()
的问题...有数百个,但没有一个得到这个。这个问题很相似,但是在尝试了答案(检查权限,检查树是否存在)后,我仍然有这个问题。
当尝试使用 fopen
创建文件时,我调用该函数并为其提供所需的参数,但它会抛出警告:"没有这样的文件或目录"。但是,检查树会发现目录确实存在。代码是这样的:
$target_dir = "/files/" . usernameIs() . "/";
$target_file = $target_dir . basename($_FILES["uploadedFile"]["name"]);
...
$file = fopen($target_file, "w+");
fclose($file);
$target_file
最终包含/files/ArtOfCode/icon.png
(用户名是ArtOfCode,我用来测试的uploadedFile
的name
是icon.png。
目录树如下所示:
public_html
> /upload
> /upload.php (the calling script)
> /action.php (this script)
> /files
> /ArtOfCode
我收到两个警告,都与fopen()
有关:
Warning: fopen(/files/ArtOfCode/icon.png): failed to open stream: No such file or directory in /home/u875642593/public_html/upload/action.php on line 26
Warning: fclose() expects parameter 1 to be resource, boolean given in /home/u875642593/public_html/upload/action.php on line 27
所以,我知道该文件(/files/ArtOfCode/icon.png)不存在。但是,PHP 文档说"...如果该文件不存在,fopen
将在尝试使用它之前创建它。支持目录树确实存在,所以我被难住了。如何使此调用创建文件?
PHP 的文件系统函数(如 fopen()
及其兄弟姐妹)在文件系统路径上运行,而不是相对于 Web 服务器文档根目录的路径("Web"路径)。(如果您的 PHP 安装是这样配置的,它们也可以在像 http://example.com/file.txt
这样的流上运行,但这在这里无关紧要)。
由于您的fopen()
路径以 /
开头,文件系统会在文件系统的根目录中查找它。文件系统路径开头的/
始终表示绝对路径而不是相对路径,并且目录结构实际上并不存在于该绝对位置。
您需要找到驻留在 Web 服务器文档根目录中的files/
目录。从 uploads/
目录中的 PHP 脚本访问它,您可以使用 ..
伪目录来执行此操作,这意味着"高一个目录",是获取同级目录的好方法。
$target_dir = "../files/" . usernameIs() . "/";
以上结果为相对路径。您可以将其包装在 realpath()
中以将其展开为完整路径。
不过,我会更频繁地使用 __DIR__
常量来获取当前文件的目录,然后遍历..
$target_dir = __DIR__ . "/../files/" . usernameIs() . "/";
最后,$_SERVER['DOCUMENT_ROOT']
也是一种选择。在您的情况下,files/
位于 Web 服务器文档根目录内,因此您还可以使用:
$target_dir = $_SERVER['DOCUMENT_ROOT'] . "/files/" . usernameIs() . "/";
您还可以考虑定义一个常量来保留应用程序的文件系统根目录,您可以在执行include/require
等时引用该常量。
define("APPLICATION_ROOT", '/home/u875642593/public_html');
不过,在您的确切情况下并没有太多好处,因为您的项目已经在文档根目录下。如果您需要将其移动到其他目录,例如如果您在 /home/u875642593/public_html/dev
中保留了开发版本,它确实会有所帮助。