上传大小限制:Nginx 与 PHP 两处都要改
发布时间:2026-04-21 11:49       
更新时间:2026-04-21 19:52
上传大文件报 413,只改 Nginx 往往没用,因为限制有两层:Nginx 拦一道,PHP 再拦一道,两处都改到位才行,漏改任何一层,症状都是时灵时不灵,反而更难排查。
Nginx 侧
client_max_body_size 默认只有 1m,在 http、server 或 location 任一层设置:
client_max_body_size 20m;
放 server 块对整站生效,只想放宽某个上传接口就写进对应的 location,影响面更小。这个值不够时,Nginx 在请求体读到一半就会直接返回 413,用户端表现有时不是看到 413 页面,而是上传进度条走到一半报连接被重置,这个特征记熟了能少走很多弯路。
PHP 侧
php.ini 里三个参数联动:
upload_max_filesize = 20M
post_max_size = 20M
memory_limit = 128M
upload_max_filesize 限制单个文件,post_max_size 限制整个请求体,后者必须不小于前者,因为请求里除了文件还有表单字段。改完 systemctl reload php-fpm 生效。这三项也能在 .user.ini 或 fpm 池配置里按目录、按站点覆盖,共用机器上更适合用后者,只对相应站点生效,不牵连其他项目。
超时联动
大文件传输时间长,两组超时容易撞上:Nginx 的 fastcgi_read_timeout 默认 60 秒,PHP 的 max_execution_time 默认 30 秒。局域网内够用,走公网传大包建议都放宽到 300。另外别漏了链路里的其他环节——前端 CDN、反代、客户端自己的超时也要对齐,任何一环断了都是上传失败,排查时用二分法:先在内网直连服务器传一次,确认服务端没问题,再去查外层链路。
验证与典型报错
传一个 20M 以内的文件实测,phpinfo 页面可以确认当前生效值。两种报错各对应一层:Nginx 直接返回 413 Request Entity Too Large,是 client_max_body_size 不够;提交后 $_FILES 是空的、程序报缺少文件字段,多半是 post_max_size 小于请求体,PHP 把超限数据整个丢弃了。按现象对号入座。改完记得 Nginx 和 php-fpm 两边都要 reload,只重载一边,就会出现"明明改了却没生效"的假象。顺带一句边界:这套调法适合几十兆以内的常规上传,上百兆的大文件建议程序侧做分片上传,比无限调大限制稳定得多,顺带还能支持断点续传,用户体验完全不同。