PHP大文件上传超时需同步调整upload_max_filesize、post_max_size、max_execution_time、max_input_time四参数,且须匹配Nginx/Apache及代理层超时配置,单改无效;推荐前端分片上传替代硬调参数。

PHP 接收大文件上传超时,本质是 upload_max_filesize、post_max_size、max_execution_time、max_input_time 四个配置共同作用的结果,单改一个通常无效。
为什么改了 upload_max_filesize 还上传失败?
因为 PHP 的上传流程分三步:HTTP 请求体接收 → 文件临时存储 → 脚本处理。每步都有独立限制:
-
upload_max_filesize只控制单个上传文件大小上限(如200M) -
post_max_size必须 ≥upload_max_filesize+ 表单其他字段开销,否则整个 POST 请求被截断(常见错误:$_FILES为空,$_POST也为空) -
max_execution_time控制脚本总执行时间,大文件写入临时目录或后续移动操作可能超时(尤其在慢磁盘或 NFS 上) -
max_input_time控制 PHP 解析整个请求(含文件流读取)的最长时间,Nginx/Apache 代理下常被忽略,但 CLI 或某些 FastCGI 配置下会生效
如何安全地调高上传限制?
必须同步调整 PHP 和 Web 服务器两级配置,缺一不可:
- PHP 层(
php.ini):upload_max_filesize = 512M post_max_size = 512M max_execution_time = 600 max_input_time = 600 memory_limit = 1G
注意:memory_limit需足够容纳文件内容(即使用move_uploaded_file(),PHP 内部仍需分配缓冲区) - Web 服务器层:
- Nginx:在
server或location块中加client_max_body_size 512M; - Apache:在
.htaccess或虚拟主机配置中加LimitRequestBody 536870912(单位字节) - PHP-FPM:检查
request_terminate_timeout和request_slowlog_timeout,避免被 FPM 主动 kill
- Nginx:在
上传过程中卡住或报 504/502 怎么排查?
这不是 PHP 问题,而是反向代理或网关超时。典型现象:浏览器进度条停在 99%,几秒后返回 504 Gateway Timeout。
立即学习“PHP免费学习笔记(深入)”;
- Nginx 侧需同步调高:
proxy_connect_timeout 600; proxy_send_timeout 600; proxy_read_timeout 600;
(如果用fastcgi_pass,对应换成fastcgi_connect_timeout等) - Cloudflare 用户:免费版默认 100 秒超时,无法修改;需升级或绕过(如前端分片上传)
-
浏览器端可监听
XMLHttpRequest.upload.onprogress判断是卡在上传还是服务端处理
大文件上传不该只靠调参数
硬调超时和大小上限只是权宜之计。真实生产环境里,upload_max_filesize 超过 2GB 就可能触发 PHP 的 32 位整数溢出($_SERVER['CONTENT_LENGTH'] 解析异常),且单次上传缺乏断点续传、校验、并发控制能力。更稳妥的做法是前端用 File API 分片,后端用 $_FILES['file']['tmp_name'] 接收每片再合并,把大文件拆成可控的小请求。否则,哪怕所有 timeout 都设为 0,网络抖动或用户中途关闭页面也会导致临时文件残留、磁盘占满。











