PHP文件上传失败需同时调整upload_max_filesize和post_max_size,且Nginx的client_max_body_size也必须匹配,改后须重启服务并确认生效的php.ini路径。

上传报错 upload_max_filesize 超限,但改了没用?
不是改完就能生效——PHP 的文件上传限制由两个配置项共同控制:upload_max_filesize 和 post_max_size。后者必须 ≥ 前者,否则即使 upload_max_filesize 设为 100M,只要 post_max_size 还是默认的 8M,ThinkPHP 仍会收到空文件或直接截断请求。
-
upload_max_filesize控制单个文件上限(如20M) -
post_max_size控制整个 POST 请求体上限(含所有字段+文件,建议设为25M或更高) - 改完后必须重启 Web 服务(
php-fpm或 Apache/Nginx),仅 reload 不够 - ThinkPHP 自身不校验这些值,错误实际来自 PHP 底层,所以日志里看不到 TP 报错,只有
$_FILES为空或error为UPLOAD_ERR_INI_SIZE
ThinkPHP 拿不到上传文件,$_FILES 是空数组?
常见于 Nginx + PHP-FPM 环境下,Nginx 自身也有上传限制,且优先级高于 PHP 配置。即使 php.ini 改对了,Nginx 的 client_max_body_size 没调,请求在到达 PHP 前就被拒绝了。
- 检查 Nginx 配置:确认
client_max_body_size(如25m)已设在http、server或location块中 - 注意单位写法:
25m(小写 m)合法,25M会报配置错误 - 修改后执行
nginx -t && nginx -s reload,否则无效 - Apache 用户需检查
LimitRequestBody(单位是字节),例如LimitRequestBody 26214400对应 25MB
ThinkPHP 上传成功但文件被截断或损坏?
这往往不是 TP 的锅,而是 memory_limit 不足导致 PHP 在处理大文件时内存溢出,中断了读取流程。尤其使用 move_uploaded_file() 前若做了额外操作(如图像处理、内容校验),更易触发。
- 检查
memory_limit是否 ≥upload_max_filesize的 2–3 倍(例如上传 20M 文件,建议设为64M或128M) - 避免在上传回调中一次性读取整个文件到内存:
file_get_contents($_FILES['file']['tmp_name'])很危险 - ThinkPHP 的
$request->file()默认走临时路径,安全;但若手动用fopen打开tmp_name并fread全量,就可能崩 - 可通过
ini_get('memory_limit')和memory_get_usage(true)在上传逻辑前加简单监控
本地能传,线上报错,但 phpinfo 显示配置一致?
PHP 可能加载了多个 php.ini 文件,CLI 和 Web SAPI 使用的配置不同。ThinkPHP 运行在 Web 环境下,必须确认你改的是 Web 对应的那个 php.ini。
立即学习“PHP免费学习笔记(深入)”;
- 在 ThinkPHP 控制器里加
echo php_ini_loaded_file();,看实际加载路径 - 运行
php --ini查 CLI 的配置,和 Web 的无关 - 有些主机商(如宝塔、cPanel)会为每个站点单独生成
php.ini,改全局文件没用 - 部分云环境(如阿里云函数计算、Serverless)根本不允许改
php.ini,只能靠代码绕过(如前端分片上传)
client_max_body_size 和 PHP 多配置文件场景下的误改——这两处查不到日志,也看不出报错,只表现为“上传无声失败”。


















