上传失败主因是php及web服务器配置限制,需同步调整upload_max_filesize、post_max_size、client_max_body_size、max_input_time和max_execution_time等参数,并确保临时目录权限正常。

上传超时或直接 500,先查 upload_max_filesize 和 post_max_size
ThinkPHP 本身不控制文件大小上限,它只是接收 PHP 已经解析完的 $_FILES。如果文件在 PHP 解析阶段就被拦下,$_FILES 根本为空,控制器里连 $request->file() 都拿不到,更不会进验证逻辑。
常见现象:选完大文件点上传,页面卡住几秒后跳 500 或空白;$_FILES 打印出来是空数组;日志里看不到 ThinkPHP 的上传相关记录。
-
upload_max_filesize必须 ≥ 你期望上传的单个文件大小(如100M) -
post_max_size必须 ≥upload_max_filesize+ 其他表单字段总长(一般设为略大,如128M) - 改完要重启 PHP-FPM 或 Apache,仅 reload 不生效
- Nginx 还要同步检查
client_max_body_size,否则请求根本到不了 PHP 层
max_execution_time 和 max_input_time 导致上传中途断掉
大文件上传耗时长,PHP 默认的 max_execution_time=30 是指脚本总执行时间,包括接收 POST 数据的时间。但 PHP 实际用 max_input_time 控制「接收全部输入(含文件)」的最长时间,单位秒。这两个值都可能让上传被中断,报错类似 PHP Warning: Unknown: Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini(注意:这行错误其实是另一回事,但常被误判)。
- 上传 500MB 文件,网络慢时可能需要 2–3 分钟,
max_input_time至少设为300(5 分钟) -
max_execution_time建议同步调高,否则后续移动临时文件、验 MD5 等操作可能超时 - 这些值在 CLI 模式下无效,只影响 Web SAPI(如 FPM)
- 别在代码里用
set_time_limit(0)试图兜底——它不作用于输入接收阶段
ThinkPHP 的 $request->file() 返回 null,但 PHP 日志没报错
说明 PHP 成功接收了文件,临时存到了 sys_get_temp_dir() 下,但 ThinkPHP 在封装过程中因校验失败或路径问题丢弃了它。最常见原因是上传表单的 name 和控制器里写的不一致,或者用了数组式命名但没按规则取。
- 确认 HTML 表单中
<input type="file" name="photo">,控制器必须写$request->file('photo'),大小写、下划线都不能错 - 如果前端传的是
<input type="file" name="files[]">,得用$request->file('files')(不是files[]),返回数组 - 检查
phpinfo()中file_uploads是否为On,有些生产环境会关掉 - 临时文件路径磁盘满、权限不足(如 www-data 无法读写
/tmp)也会导致$request->file()返回 null,但 PHP 错误日志里会有Unable to create temporary file提示
调试时 $_FILES 有数据,但 ThinkPHP 报 File upload error
这是 ThinkPHP 自己抛出的异常,意味着文件已进入框架流程,但在移动、验证或保存环节失败。重点看异常堆栈里的具体提示,比如 move_uploaded_file(): Unable to move 或 File is too large。
- 检查
moveUploadedFile()目标目录是否存在、可写,且父目录不能是 open_basedir 限制外的路径 - ThinkPHP 的
validate(['size' => 1024 * 1024 * 100])是应用层校验,和 PHP 配置无关,但会覆盖默认行为,记得确认是否误加了过严规则 - 如果用了分片上传,确保前端传的
chunk、chunks、filename参数名和后端接收逻辑对得上,ThinkPHP 不内置分片支持,全靠自己处理$_FILES - Apache 的
LimitRequestBody指令也可能拦截,尤其在虚拟主机配置里被单独设了小值
真正卡住的地方往往不在 ThinkPHP 代码里,而在 PHP 配置、Web 服务器限制、临时目录状态这三个交界处。调的时候别急着翻框架源码,先 var_dump($_FILES) 和 error_log(print_r(ini_get_all(), true), 3, '/tmp/php-ini.log') 看一眼,比猜快得多。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











