PHP 大文件上传失败需同步调整 upload_max_filesize、post_max_size、max_execution_time、memory_limit 等参数,且 Nginx 的 client_max_body_size 及代理限制也必须配置,仅调 upload_max_filesize 无效。

PHP 大文件上传失败,upload_max_filesize 调了没用?
改了 upload_max_filesize 还是报错“File upload error - 1”或直接 413、500,大概率不是它单独的问题。这个值只是上传流程里的一环,必须和 post_max_size、max_execution_time、memory_limit 同步调,否则改了也白改。
-
post_max_size必须 ≥upload_max_filesize(比如设 200M,前者至少 200M,建议 +10M 留余) -
max_execution_time和max_input_time要足够长——1GB 文件走普通 HTTP 上传,几十秒到几分钟很常见 -
memory_limit建议 ≥upload_max_filesize的 2 倍,PHP 在解析 multipart body 时会暂存部分数据在内存
修改位置:php.ini vs .htaccess vs ini_set()
只有 php.ini 能真正生效;.htaccess 在 Apache + mod_php 下可能起作用,但 Nginx 完全不认;ini_set() 对 upload_max_filesize 和 post_max_size 是无效的——这两个是 PHP 的「PHP_INI_PERDIR」指令,运行时不可变。
- 确认当前生效的
php.ini路径:执行php --ini或查看phpinfo()页面里的“Loaded Configuration File” - 改完必须重启 Web 服务(
systemctl restart php-fpm+systemctl restart nginx或apache2) - 验证是否生效:写个
test.php输出ini_get('upload_max_filesize')和ini_get('post_max_size')
上传超时卡死、Nginx 返回 413 Request Entity Too Large
Nginx 有自己的上传限制,和 PHP 完全无关。即使 PHP 全部调大,Nginx 拦在门口,请求根本到不了 PHP。
- 检查 Nginx 配置里是否有
client_max_body_size,默认通常是 1M - 必须在
http、server或location块中显式设置,例如:client_max_body_size 200M; - 改完要
nginx -t && systemctl reload nginx,只 reload 就行,不用 restart - 如果用 Cloudflare 等代理,还要确认它们的上传限制(CF 默认 100MB,企业版可提)
大文件上传的实际瓶颈往往不在配置
配全了还是传一半断、进度条卡住、$_FILES 为空?那大概率是网络不稳定、客户端中断,或者用了不支持分片的前端库硬扛 GB 级文件。
立即学习 “PHP 免费学习笔记(深入)”;
- 浏览器原生
<input type="file">上传大文件极易因网络抖动失败,无重试、无断点续传 - 生产环境强烈建议换方案:用
resumable.js、uppy或自研分片 + 合并,后端配合move_uploaded_file()接收每片再拼接 - 临时文件目录(
upload_tmp_dir)磁盘空间和权限也要检查——PHP 默认用/tmp,小内存 VPS 上 /tmp 可能是内存盘且空间极小
配齐所有参数只是起点,真正的难点在稳住整个链路:从用户点击上传,到 Nginx 接收,到 PHP 解析,再到你把文件落盘或转存,每一环都可能无声失败。尤其别忽略客户端体验和 fallback 方案。