我有以下查询(apache,php-7.4.33,mysql):
SELECT [blah] from [blah] INTO OUTFILE $tmpfile FIELDS TERMINATED BY ',' FIELDS TERMINATED BY '\n';
我正在尝试使用此代码从服务器下载此内容:
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false);
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=\"contacts.csv\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize( $tmpfile ));
readfile( $tmpfile );
unlink( $tmpfile );
我收到有关 filesize()、readfile() 和 unlink() 的错误消息,并且上传的文件为空,例如:
PHP Warning: filesize(): stat failed for /tmp/contacts-25178.csv in /[blah]/index.php
如果我进入命令行,该文件就存在:
$ ls -l /tmp/contacts-25178.csv
-rw-r--r-- 1 mysql mysql 151253 Jan 24 21:29 /tmp/contacts-25178.csv
有人可以帮我解释一下吗?
-rw-r--r--
这表示每个人都应该能够读取该文件,但这仅适用于他们可以读取文件所在的路径(即每个目录)。
/tmp/
在 Unix 系统上,每个人通常都可以访问 /tmp,但是如果您
ls -ld /tmp
,您应该会看到类似这样的权限:
drwxrwxrwt
看到最后的“t”了吗?这意味着一些特别的东西。但同样,它不应该阻止读取文件。
因此,根据您提供的信息,您的 PHP 代码没有理由无法读取该文件。但还有另外两种可能性:
您的 PHP 服务正在 chroot 环境中运行 - 它无法到达 /tmp 目录
有强制访问控制系统阻止访问。这可能是 RHEL/衍生品上的 SELinux、Debian 等上的 Apparmor,或者可以通过 systemd 文件系统名称空间(阻止或重新映射)来实现。请参阅https://serverfault.com/questions/847156/is-there-a-way-to-control-filesystem-access-with-systemd
提及它正在运行的操作系统/发行版以及您如何获取/部署 PHP 运行时将会减少 Poissibilites。