改了 upload_max_filesize 仍上传失败,因 PHP 8.5.5 配置解析更严格、单位须大写、Web 服务器与云环境存在独立限制,且需同步调大 post_max_size 和 memory_limit 并重启服务。

改了 upload_max_filesize 还是传不上去?不是 PHP 没生效,而是其他环节卡住了——PHP 8.5.5 对配置解析更严格,单位写错、路径搞混、Web 服务器拦截,都会让设置形同虚设。
确认 php.ini 实际加载路径和生效项
PHP 8.5.5 不再容忍模糊配置:单位必须大写(M、G),带空格或小写(如 128m 或 128 M)会被当成 0;CLI 和 Web SAPI 加载的 php.ini 完全不同。
- 运行
php --ini查看 CLI 加载路径,但 Web 请求用的是phpinfo()页面里 “Loaded Configuration File” 显示的路径 - 在 PHP 脚本中加
var_dump(ini_get('upload_max_filesize'), ini_get('post_max_size'));,输出必须是字符串如"256M",不是false或空 - Docker 或宝塔用户优先检查是否被覆盖:有些镜像把主配置放在
/usr/local/etc/php/conf.d/下的 .ini 文件里,而非传统位置
必须同步调大的三个核心参数
upload_max_filesize 只管单个文件,真正拦住请求的是 post_max_size ——它包含所有表单字段 + 所有文件总大小。PHP 8.5.5 解析失败时不会报错,只会静默截断 multipart 数据,导致 $_FILES 为空或报 UPLOAD_ERR_NO_FILE。
-
upload_max_filesize = 256M(单文件上限) -
post_max_size = 260M(建议比前者略大,留出 header 和字段空间) -
memory_limit = 384M(至少 >post_max_size,否则文件读入内存时直接 OOM) - 顺手调高
max_execution_time = 600和max_input_time = 600,避免超时中断上传
Nginx / Apache 层不能漏掉
413 错误、Missing boundary in multipart data 这类提示根本不是 PHP 报的——请求压根没进 PHP,被 Web 服务器提前拒收了。
立即学习“PHP免费学习笔记(深入)”;
- Nginx:必须在
server或location块里写client_max_body_size 260M;,写在http块可能被子配置覆盖 - Apache:检查
LimitRequestBody(单位是字节),设为0表示不限,或明确写272629760(260 × 1024 × 1024) - 云环境(如 Cloudflare、阿里云 SLB)也有独立 body size 限制,默认常为 100MB,PHP 和 Nginx 改得再大也没用
代码层校验和动态设置的边界
ini_set() 在 PHP 8.5.5 中依然受限:它不能突破 php.ini 里设定的硬上限,且在 PHP-FPM 或某些 SAPI 下默认被禁用(查看 ini_get('disable_functions') 是否含 ini_set)。
- 仅适合临时策略,例如多租户系统按用户等级动态设限
- 务必配合前端隐藏域
<input type="hidden" name="MAX_FILE_SIZE" value="268435440">(单位字节),这是浏览器端提示,不影响服务端限制 - 业务代码必须自己检查
$_FILES['file']['size']和$_FILES['file']['error'],尤其要捕获UPLOAD_ERR_INI_SIZE和UPLOAD_ERR_FORM_SIZE
最易被忽略的点:改完配置后,systemctl restart php8.5-fpm nginx 是必须的——只 reload Nginx 不会重载 PHP-FPM 的 ini 配置,而只重启 PHP-FPM 又会让 Nginx 继续用旧的 client_max_body_size 拦截请求。



















