PHP download file from /var folder without relative paths
我想从 Web 根目录上方的文件夹中下载文件。假设我想得到这个文件:
我的代码是:
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 并且它正在工作。任何想法为什么会发生这种情况?
- pdfs 文件夹有读取权限吗?
-
恕我直言,有同样的问题,检查一下。 stackoverflow.com/a/17896538/6557808
-
@KrzysztofDuszczyk 是的,我编辑了我的问题。
-
嗯,当我重现问题时,向 pdfs 文件夹添加执行权限会有所帮助。真的不知道为什么:)
-
@KrzysztofDuszczyk Wtf。你说得对!它在工作。好吧,现在我很困惑。
-
我也想知道为什么会这样。除了 forums.opensuse.org/showthread.php/...
-
您使用的是什么操作系统,是否启用了 SELinux?我复制了您的情况,并且 file_exists 对于权限为 755 的目录中权限为 644 的文件返回 true。在 Linux 上,PHP 只是调用函数 access() 来确定文件可访问性,因此操作系统中的某些内容表示除非还设置了执行,否则无法访问该文件。
-
@drew010 我正在运行 Debian 8.5 ,不,我没有 SELinux。
-
ubuntu 14.04 在这里。当文件的权限为 644,文件夹的权限为 755 时,问题是文件夹具有 644 权限。
-
请参阅此答案的要点 3。基本上在目录上执行是允许用户进入目录并列出/读取内容的。
-
@drew010 哇,有趣!我不知道谢谢!能否请您将其写在答案中以便我接受?
问题(不是在这种情况下,但我把它留给别人帮助)
如果您知道该文件确实存在于磁盘上,则您的 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,或者在脚本顶部使用以下行:
请注意,PHP 删除了 5.4 版本的 safe mode 设置,因此如果您最近安装了 PHP,您的问题可能在其他地方。
- 我尝试在我的 php 脚本之上添加 ini_set("safe_mode_include_dir","/var/pdfs/"); 。我没有工作,所以我尝试了您的第二个解决方案,但它也没有工作。
-
我想你误会了。我不建议您使用 ini_set 来更改 safe_mode_include_dir。我建议您直接在 php.ini 中进行更改。第二个建议是对第一个建议的补充(不是替代方案),因此无论哪种方式,您都需要先更改 php.ini。
-
好的。我打开了我的 /etc/php5/apache2/php.ini 但没有 safe_mode_include_dir 选项。甚至没有注释掉。我应该附加它吗?
-
首先,您需要知道它是 PHP 启动时实际加载的 php.ini (关于其他地方如何进行的大量讨论),因为该文件通常有多个副本。获得正确的文件后,如果不存在,请添加设置。然后,您必须重新启动 Apache 才能使更改生效。顺便问一下,您运行的是什么版本的 PHP?
-
我正在运行 PHP 5.6.20-0+deb8u1。我将它附加到 php.ini 但仍然没有。
-
显然,当我向 pdfs 文件夹添加执行权限(归功于 Krzysztof Duszczyk)时,它正在工作。任何想法为什么?
-
行。 PHP 5.6.20 不再使用 safe mode (从 5.4 开始删除)。您可以撤消您的编辑。其他事情可能正在发生。