根本原因是PHP的upload_tmp_dir配置为空、路径不存在或权限不足,且需同时满足存在、可写、在open_basedir白名单、非只读文件系统四个条件。

upload_tmp_dir 未设置或路径不可写
ThinkPHP 报 Missing temporary folder,根本原因不是框架问题,而是 PHP 底层找不到可用的临时目录来存上传的文件碎片。PHP 的 upload_tmp_dir 配置项为空、指向了不存在的路径,或者 Web 进程(如 www-data、nginx 用户)没权限往里写,都会触发这个错误。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 检查
phpinfo()输出中upload_tmp_dir的值;若为空,说明 PHP 正在 fallback 到系统默认临时目录(如/tmp),但该目录可能被禁用或权限受限 - 在
php.ini中显式设置:upload_tmp_dir = /var/www/tmp(路径需真实存在) - 确保该目录由 Web 服务器用户拥有且可写:
sudo chown www-data:www-data /var/www/tmp && sudo chmod 755 /var/www/tmp - 重启 PHP-FPM 或 Apache 后再验证,别只 reload
open_basedir 限制拦截了临时目录
即使 upload_tmp_dir 设置正确,如果启用了 open_basedir,而临时目录不在允许路径列表里,PHP 会直接拒绝使用它,报错仍为 Missing temporary folder —— 这个误导性很强,容易让人反复检查 upload_tmp_dir 却忽略安全限制。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 查看当前生效的
open_basedir值(phpinfo()或ini_get('open_basedir')) - 若非必要,建议关闭
open_basedir;若必须开启,需把upload_tmp_dir路径加进白名单,例如:open_basedir = "/var/www/:/var/www/tmp/" - 注意末尾斜杠和路径分隔符,多个路径用冒号(Linux)或分号(Windows)分隔,不能漏掉
ThinkPHP 自定义上传配置没绕过 PHP 底层限制
有人试图在 ThinkPHP 的 File::upload() 或配置里改 root、savePath,以为能跳过临时目录问题——不行。这些只是控制“上传成功后存哪”,而 Missing temporary folder 发生在 PHP 接收阶段,早在 ThinkPHP 拿到文件前就失败了。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 确认错误发生在
$_FILES解析阶段(比如var_dump($_FILES)是空或error = 6),这就和框架无关 -
$_FILES['xxx']['error'] === 6就是 PHP 官方定义的UPLOAD_ERR_NO_TMP_DIR,直指upload_tmp_dir失效 - 不要在控制器里 try-catch 这个错误并提示“上传失败”,要先确保 PHP 环境就绪;否则用户看到的永远是模糊提示
容器或云环境下的临时目录特殊处理
Docker、宝塔、某些云虚拟主机默认不挂载或不开放系统 /tmp,或者把 upload_tmp_dir 指向了内存文件系统(如 /dev/shm),但没配好权限或大小限制,也会导致上传中途失败并报同个错误。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在容器中,推荐挂载一个专用卷给临时目录:
-v /host/tmp:/var/www/tmp,并在php.ini中固定指向它 - 检查
df -h /var/www/tmp是否满;小内存容器里/dev/shm默认只有 64MB,大文件上传会静默失败 - 云主机若用 suhosin 或 mod_security,也可能拦截临时文件创建,需查
error_log里更底层的拒绝记录
真正卡住人的地方,往往不是 ThinkPHP 怎么写,而是 PHP 进程压根没机会把文件扔进临时区——那个 upload_tmp_dir 路径得同时满足“存在、可写、在 open_basedir 白名单里、不在只读文件系统上”四个条件,缺一不可。



















