ThinkPHP文件上传失败应先排查四个关键点:一、检查表单enctype和method、PHP file_uploads是否开启;二、确认upload_max_filesize、post_max_size及Nginx client_max_body_size设置并重启PHP-FPM;三、确保临时目录和目标目录存在且Web用户有写权限;四、通过$_FILES'avatar'原始错误码精准定位问题。

ThinkPHP部署后文件上传失败,多数情况不是代码写错了,而是环境配置或权限没对上。别急着改框架逻辑,先按顺序快速排查这四个关键点。
一、看表单和 PHP 基础开关通没通
这是最常被跳过的一步——文件根本没进 PHP,后面所有操作都是空转。
- 检查 HTML 表单是否带
enctype="multipart/form-data",且<form>标签里不能漏掉 -
<input type="file" name="avatar">的name值,必须和控制器里$request->file('avatar')完全一致(大小写敏感) - 确认表单
method="POST",GET 不传文件 - 运行
phpinfo()或var_dump(ini_get('file_uploads')),确认file_uploads = On已生效(注意:Nginx+PHP-FPM 场景下,要查/etc/php/*/fpm/php.ini,不是 CLI 配置)
二、查 PHP 上传大小限制有没有卡住
页面空白、$_FILES 为空、或报 error=1,大概率是被截断了。
-
upload_max_filesize必须 ≥ 你要传的单个文件大小(比如传 50MB 视频,至少设50M) -
post_max_size必须 ≥upload_max_filesize,还要预留一点空间给其他表单字段(建议多加 5–10MB) - 修改后必须重启 PHP-FPM(如
sudo systemctl restart php8.1-fpm),仅 reload Nginx 不生效 - 如果用 Nginx,额外检查
client_max_body_size是否同步调大,否则请求压根到不了 PHP 层
三、盯临时目录和目标目录有没有写权限$_FILES['xxx']['error'] === 0 只代表 PHP 接收成功,不代表能存出去。
- 运行
echo sys_get_temp_dir();查临时目录路径(通常是/tmp),确认 Web 用户(如www-data或nginx)有读写权限 - 目标目录(如
public/uploads)必须提前存在,ThinkPHP 不会自动创建父级目录 - 执行
mkdir -p public/uploads && chown -R www-data:www-data public/uploads(Ubuntu)或chown -R nginx:nginx public/uploads(CentOS) - 权限设
755足够,别用777(安全风险高)
四、验证错误码,别被框架封装绕晕
ThinkPHP 的 getError() 有时不返回真实原因,得看原始值。
- 在控制器里加一行:
var_dump($_FILES['avatar']['error']); - 对照 PHP 常量判断:
-
0→ 上传成功,可继续 move -
1或2→ 大小超限(PHP 或表单 MAX_FILE_SIZE) -
6→upload_tmp_dir未配置或不可写 -
7→ 磁盘满或 SELinux/AppArmor 拦截
-
- 调用
$file->move()前,务必先检查$file->getInfo()['tmp_name']是否非空,为空说明临时文件根本没生成
不复杂但容易忽略



















