php实际临时目录按tmpdir→sys_temp_dir→upload_tmp_dir→系统默认顺序确定,需用php -i | grep -e 'sys_temp_dir|upload_tmp_dir|tmpdir'查真实路径,/tmp非必用;滞留文件多因异常退出或未unlink,应先lsof +l1确认无活跃句柄再清理;建议显式配置sys_temp_dir、优先用tmpfile()、加shutdown兜底,并关注deleted但未关闭的fd导致空间不释放问题。

查清PHP实际用的临时目录在哪
PHP不总是用系统默认的 /tmp,它会按顺序找:环境变量 TMPDIR → sys_temp_dir 配置项 → upload_tmp_dir → 系统默认(/tmp 或 Windows 的 C:\Windows\Temp)。只盯着 /tmp 清,可能根本没动到真正在用的目录。
执行这行命令看真实路径:php -i | grep -E 'sys_temp_dir|upload_tmp_dir|TMPDIR'
- 如果输出里
sys_temp_dir是空或未定义,说明 PHP 正在 fallback 到系统默认路径 - 如果
upload_tmp_dir显式设为/var/www/tmp,那/tmp再大也和你上传失败无关 - 某些 Docker 环境中,
TMPDIR被设为/dev/shm,而那里是内存挂载点,满了会导致Cannot allocate memory错误,不是磁盘满
为什么 /tmp 里一堆 phpXXXXXX 文件删不干净
这些是 tempnam()、tmpfile() 或框架(如 Laravel 的 Filesystem)生成的临时文件,但脚本异常退出、未调用 unlink()、或用了 register_shutdown_function() 却没正确触发,都会让它们滞留。
- 别直接
rm -rf /tmp/php*—— 可能误删正在被 PHP-FPM worker 持有的句柄(lsof +L1会显示 DEL 状态),删了也不释放空间 - 更安全的做法:先
lsof +L1 | grep php,确认没有活跃进程还占着这些文件;再批量清理 - 检查代码里是否漏了
unlink($tmpFile),尤其在try/catch外围没兜底时,异常跳出会跳过清理逻辑
怎么让PHP自动清理或换掉高危临时目录
硬清只是救火,关键得堵住源头。两个方向:改路径、加清理逻辑。
- 在
php.ini中显式设置sys_temp_dir = /var/tmp/php(确保该目录存在且www-data可写),避免和系统其他服务混用/tmp - 用
tmpfile()替代tempnam():前者返回资源句柄,脚本结束自动释放;后者返回路径,必须手动unlink() - 对必须用
tempnam()的场景,加register_shutdown_function()做兜底:register_shutdown_function(function() use ($tmpFile) { if (file_exists($tmpFile)) unlink($tmpFile); }); - 若用的是 Laravel 或 Symfony,检查是否启用了
cache:clear时顺带清理sys_get_temp_dir()下过期文件的钩子——多数框架不干这事,得自己补
清理后空间没释放?重点看 deleted 但未关闭的文件
这是最常被忽略的一环:文件删了,但进程还开着 fd,磁盘空间不会还给系统。
运行:lsof +L1 | awk '$5 == "DEL" {print $2, $9}' | sort -u
- 输出里如果有
php-fpm或apache2的 PID,说明它正往一个已被删除的临时文件里写数据 - 这时
du -sh /tmp看不到它,但df显示已满——因为 inode 还被占着 - 稳妥解法:
kill -USR1 <pid></pid>(如果 PHP-FPM 配置了catch_workers_output = yes并支持日志重开),否则只能重启服务 - 临时应急:用
echo > /proc/<pid>/fd/<fd_num></fd_num></pid>清空对应 fd 内容(需 root 权限,慎用)
lsof +L1 和 php -i 输出,比盲目 rm -rf 有用得多。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











