You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP文件函数(filesize、readfile、unlink)无法读取MySQL生成的文件

问题

在Apache环境下使用PHP 7.4.33与MySQL,执行以下查询语句将数据导出到临时文件$tmpfile:

SELECT [blah] from [blah] INTO OUTFILE $tmpfile FIELDS TERMINATED BY ',' FIELDS TERMINATED BY '\n';

随后通过以下PHP代码尝试下载该文件:

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

请问该问题的原因是什么?

原因分析

  • 进程属主不匹配
    从命令行输出可知,导出文件的属主和属组均为mysql用户,而Apache/PHP进程通常以apache(部分系统为www-data)用户运行。尽管文件权限设置为-rw-r--r--(其他用户拥有读权限),但跨用户的文件访问会被系统安全机制限制,导致PHP进程无法读取该文件。

  • SELinux安全策略拦截
    若系统开启了SELinux(常见于CentOS、RHEL等发行版),即便文件权限符合要求,SELinux的上下文标签机制也会阻止Apache进程访问MySQL生成的文件。MySQL在/tmp目录下创建的文件带有mysql_db_t类安全标签,而Apache进程仅能访问带有httpd_sys_content_t或httpd_tmp_t标签的文件,两者标签不匹配会直接触发访问拦截。

  • SQL语句语法错误(次要)
    你的SQL查询中重复使用了FIELDS TERMINATED BY,正确写法应为FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'。该错误仅会导致导出的CSV格式异常,不会直接引发PHP无法读取文件的问题,但建议修正以保证导出数据格式正确。

内容的提问来源于stack exchange,提问作者Robert S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 13:57:46