ThinkPHP文件上传需同步调整PHP、Web服务器、框架三层限制:PHP层设upload_max_filesize和post_max_size;Nginx加client_max_body_size;框架validate()中size单位为字节且须显式调用。

ThinkPHP 文件上传大小限制不是单靠改框架配置就能解决的,必须从 PHP 底层、Web 服务器、框架校验三层同步调整。任一层卡住,上传就会失败——比如报 413 Request Entity Too Large(Nginx 拦截)、Post size exceeded(PHP 拦截)或看似成功但 $_FILES 为空(请求根本没到 PHP)。下面分三步说清楚怎么配、为什么这么配。
一、调大 PHP 底层上传限制
这是第一道硬门槛,PHP 在解析请求前就强制检查,不达标直接拒收,框架连文件对象都拿不到。
-
修改 php.ini 中两个关键参数:
upload_max_filesize = 50M(单文件上限)post_max_size = 60M(整个 POST 请求体上限,含所有字段+文件,必须 ≥ upload_max_filesize) - 可选但建议:增大
memory_limit至至少 1.5 倍post_max_size,例如memory_limit = 1G,避免内存不足中断 - 改完必须重启 PHP-FPM(如
systemctl restart php8.2-fpm),仅 reload 不生效 - 用
phpinfo()页面确认“Loaded Configuration File”路径及参数值已更新,别只信配置文件写了
二、放宽 Web 服务器请求体限制
Nginx 或 Apache 会在请求抵达 PHP 前就拦截超限数据,此时 PHP 日志无记录,浏览器只看到 413 错误。
-
Nginx 用户:在对应站点的
server块内添加client_max_body_size 60m;(数值需 ≥ PHP 的post_max_size)
同时建议加client_body_timeout 600;防止慢速上传中断 -
Apache 用户:在虚拟主机配置或
.htaccess中添加LimitRequestBody 62914560(单位字节,60MB = 62914560) - 改完必须验证并重载:
Nginx:先nginx -t测试语法,再nginx -s reload
Apache:运行apachectl configtest后systemctl reload apache2
三、设置 ThinkPHP 框架层校验规则
这一层是业务逻辑校验,只在 PHP 成功接收文件后执行,用于细化控制(如单字段限制、类型组合),不能替代前两层。
立即学习“PHP免费学习笔记(深入)”;
- 获取文件对象:
$file = $this->request->file('avatar'); - 调用
validate()方法并传入规则数组:$rule = ['size' => 52428800, 'ext' => ['jpg', 'png', 'pdf']];
注意:size单位是字节(50MB = 52428800),不能写'50M';ext必须全小写、不含点、无空格 - 必须显式调用
$file->validate($rule),否则校验不触发;未通过会抛出think\exception\FileValidateException - 若用验证器类,规则写法为:
'avatar' => 'require|fileSize:52428800|fileExt:jpg,png,pdf',同样注意单位和格式
四、其他关键细节别忽略
这些点常被跳过,却直接导致上传静默失败或中途断开。
-
临时目录权限与空间:确认
upload_tmp_dir(php.ini 中设置)路径存在、可写、有足够磁盘空间;建议设为项目内可控路径,如/var/www/your-app/runtime/upload_tmp -
超时设置:大文件上传耗时长,需同步调大:
PHP 的max_execution_time = 600和max_input_time = 600
Nginx 的fastcgi_read_timeout 600(若用 FastCGI) -
前端提示不可靠:
<input type="file" maxlength>浏览器不支持,不要依赖;大小限制必须由后端兜底 -
扩展名校验有陷阱:上传
report .pdf(带空格)会被提取为' .pdf',导致校验失败;建议用$file->getInfo('name')检查原始名



















