PHP 从 /var 文件夹下载文件,没有相对路径


PHP download file from /var folder without relative paths

我想从 Web 根目录上方的文件夹中下载文件。假设我想得到这个文件:

1
/var/pdfs/test.pdf

我的代码是:

1
2
3
4
5
6
7
8
9
10
$name ="test.pdf";
$url ="/var/pdfs/" . $name;
if (file_exists($url)) {
    header("Content-Type: application/pdf");
    header("Content-Transfer-Encoding: Binary");
    header("Content-disposition: attachment; filename='" . basename($url) ."'");
    readfile($url);
} else {
    echo"Not found: $url";
}

问题是我总是得到 Not found: $url 回声。

我的文件有读取权限:

1
2
3
4
5
thecrafter@vps136166:/var/pdfs$ ls -la
total 6484
drwxr--r--  2 thecrafter root          4096 Jul  7 00:19 .
drwxr-xr-x 13 root       root          4096 Jul  7 00:16 ..
-rw-r--r--  1 thecrafter thecrafter 6629018 Jul  7 00:18 test.pdf

还有目录:

1
2
thecrafter@vps136166:/var$ ls -la | grep pdfs
drwxr--r--  2 thecrafter root  4096 Jul  7 00:19 pdfs

我错过了什么吗?问题出在哪里?

编辑 1

Krzysztof Duszczyk 指出,如果我授予 pdfs 目录的执行权限,问题就解决了。事实上,我给了它 755 并且它正在工作。任何想法为什么会发生这种情况?


问题(不是在这种情况下,但我把它留给别人帮助)

如果您知道该文件确实存在于磁盘上,则您的 file_exists() 可能会被旨在保护 /var/pdfs/ 中的文件免遭未经授权访问的安全措施阻止。这来自 file_exists 上的文档:

Warning: This function returns FALSE for files inaccessible due to
safe mode restrictions. However these files still can be included if
they are located in safe_mode_include_dir.

解决方案(同样不是在这种情况下,但可以帮助类似的症状)

您想将目录添加到 safe_mode_include_dir 设置。在 php.ini 中找到设置,取消注释,然后添加目录:

1
safe_mode_include_dir = /var/pdfs/

如果这仍然不起作用,您可能还需要将目录添加到您的 PHP 包含路径中,方法是在 php.ini 中设置 include_path,或者在脚本顶部使用以下行:

1
2
$path = '/var/pdfs'
set_include_path(get_include_path() . PATH_SEPARATOR . $path);

请注意,PHP 删除了 5.4 版本的 safe mode 设置,因此如果您最近安装了 PHP,您的问题可能在其他地方。