Nginx 限制 ThinkPHP 文件上传本质是需主动放宽 client_max_body_size,必须在匹配上传路径的 location 块中配置(如 location /upload { client_max_body_size 200m; }),并同步调优超时、缓冲等参数及中间件限制,否则请求无法抵达 PHP。

Nginx 限制 ThinkPHP 文件上传大小,本质不是“限制”,而是必须主动放宽默认限制——因为 Nginx 默认只允许 1MB 的请求体,而 ThinkPHP 上传依赖标准 multipart/form-data 协议,整个表单(含文件二进制数据、boundary、其他字段)都打包在请求体中。只要实际体积超过 Nginx 设置,请求根本不会抵达 PHP,ThinkPHP 连 $request->file() 都拿不到,更无从验证。
所以真正要做的,是在 Nginx 中正确放开 client_max_body_size,并配套调优关联参数。
client_max_body_size 必须写在 location 块里
这个参数作用域优先级为:location > server > http。
如果只在 server 块设了 100m,但你的上传接口路径是 /api/upload,而该路径被另一个 location /api/ 块匹配且未显式配置该指令,Nginx 就会沿用默认的 1m 或继承值,导致 413 错误。
✅ 正确做法:
在匹配上传路径的 location 块内直接设置,例如:
location /upload {
client_max_body_size 200m;
client_body_buffer_size 1m;
client_body_temp_path /var/tmp/nginx/client_body 1 2;
client_body_timeout 600;
fastcgi_read_timeout 600;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
proxy_read_timeout 600;
# ThinkPHP 通常走 fastcgi_pass
fastcgi_pass php-handler;
include fastcgi_params;
}⚠️ 注意:不要只写在 http 或全局 server 块里;也不要在不相关的 location(如 location /)中配置,否则无效。
数值要留足余量,单位要写对
-
client_max_body_size控制的是整个 HTTP 请求体大小,不是单个文件大小。
实际请求体 = 所有文件二进制 + 表单字段文本 + 多个 boundary 分隔符。
比如你允许单文件最大 100MB,上传 3 个文件时,请求体可能达 102–105MB。
✅ 建议:设为比 PHP 的 post_max_size 大 10–20MB。
例如 PHP 设了 post_max_size = 192M,Nginx 就设 client_max_body_size 200m(单位小写 m 即可,不区分大小写)。
❌ 错误写法:client_max_body_size 200;(没单位 = 200 字节)、client_max_body_size "200m";(引号非必需,还可能引发语法错误)。
立即学习“PHP免费学习笔记(深入)”;
必须同步检查并放开中间层限制
Nginx 很少是最后一道网关。如果你的架构中存在:
- CDN(如 Cloudflare、阿里云 CDN)
- 负载均衡器(如 AWS ALB、腾讯云 CLB)
- WAF(Web 应用防火墙)
- 反向代理前置服务(如 Kong、Traefik)
这些中间件同样默认限制请求体大小,且多数默认上限 ≤ 10MB,有些甚至仅 2MB。它们会在请求到达 Nginx 前就返回 413,此时 Nginx 日志里完全看不到记录。
✅ 务必逐层确认:
- 查阅对应平台文档,找到
max_request_size、client_max_body_size、limitRequestBody等关键词配置项; - 将其设为 ≥ Nginx 层的值(如统一设为
200m); - 修改后保存并发布配置(CDN/WAF 类常需“发布”动作,非 reload)。
配套超时与缓冲参数不能漏
大文件上传慢,容易卡在传输中途:
-
client_body_timeout 600:客户端上传数据的空闲超时(秒),防止弱网中断; -
fastcgi_read_timeout 600:Nginx 等待 PHP-FPM 返回响应的超时(必须设,否则默认 60 秒就断); -
client_body_buffer_size 1m和fastcgi_buffer_size 32k:避免频繁磁盘刷写,提升稳定性; -
client_body_temp_path:确保路径存在、磁盘空间充足、Nginx 用户(如www-data)有读写权限。
不配这些,即使 client_max_body_size 放开了,仍可能出现 408、502、连接重置等静默失败。
ThinkPHP 本身不参与这层控制,它只在请求成功抵达 PHP 后才开始处理 $_FILES。Nginx 这一关过不去,框架连启动的机会都没有。



















