⭐ 推荐:社区规则条款 V1.0

小皮面板怎么设置 PHP 上传文件大小和超时限制?

域名注册
域名注册 版主萌新站长 👑黑卡会员
发布于 2026-10-26 09:14 ·1 浏览 ·7 回复
内容摘要

在小皮面板对应 PHP 版本的 php.ini 中调整 upload_max_filesize、post_max_size、max_execution_time、max_input_time 并重启 PHP,同时调大 Nginx 的 cli

本文转载自 GJ站长论坛,原文地址:https://www.gj0.com/thread-2573.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 7

chinaz
chinaz 初级会员萌新站长 1楼 2026-10-26 09:34

再补两块收尾:Nginx 的 client_max_body_size 和 PHP-FPM 的 request_terminate_timeout;这两处不改,php.ini 调多大都可能白搭。

站点设置 → 配置文件里,在 server{} 段加 client_max_body_size 64m;(数值跟 post_max_size 对齐或略大一点,写 64m 对应上面 66M 的 POST 上限),保存后重启 Nginx。Apache 环境对应的开关是 LimitRequestBody,默认 0 即不限制,一般不用动,但如果你之前手动设过小值,这里也要同步放开。

第二处是超时链路。max_execution_time 只管 PHP 脚本自己算的时间,FPM 那边还有个 request_terminate_timeout(默认常见 30s 或 0),Nginx 还有 fastcgi_read_timeout 默认 60s,后端跑 300 秒的话前面会被 Nginx 先掐断,页面报 504 Gateway Time-out 而不是 PHP 报错。所以 max_execution_time = 300 要配上 fastcgi_read_timeout 300s;,FPM 的 request_terminate_timeout 也设到 300 或 0。

改完别只看面板,写个 phpinfo() 页面确认 Local Value 是不是你要的值——CLI 和 FPM 用的是两份配置,SSH 里 php -i 看到的数字不代表站点生效的数字,这是最容易误判的地方。

常见坑还有两个:一是小皮多版本共存时改错目录,站点实际跑的是另一个版本;二是上传大文件失败但没报错,多半是 upload_tmp_dir 指向的临时目录空间不足或权限不对,顺带看一眼 sys_temp_dir。

满月居于空
满月居于空 萌新站长 #3006 2楼 2026-10-26 09:58
chinaz:再补两块收尾:Nginx 的 `client_max_body_size` 和 PHP-FPM 的 `request_terminate_timeout`;这两…

这条补充到位,尤其是超时链路那段,很多人只盯着 max_execution_time 改,结果页面 504,就去对 PHP 反复设置,实际是 Nginx 先超时断开连接。我接着补三点:

第一,client_max_body_size 的取值方向别搞反:它是 Nginx 的前置限制,必须大于等于 post_max_size,不能比它小。上面 post_max_size 是 66M,这里写成 64m 反而会比 PHP 先一步返回 413,写成 66m 或 70m 才稳。

第二,超时不止 read 一侧,fastcgi_connect_timeout、fastcgi_send_timeout 也建议一起抬到 300s;另外 client_body_timeout、client_header_timeout 默认 60s,客户端网速慢、传大文件卡住时会被 Nginx 直接断连,表现是连接重置而不是 504,这个比 504 更难查。改 www.conf 里的 request_terminate_timeout 后记得重载 php-fpm,只重启 Nginx 不会生效。

第三,验证时我会直接看 phpinfo 里 Loaded Configuration File 那一行的路径,一眼就知道有没有改到站点实际运行的 PHP 版本,比逐个比对 Local Value 快。

常见坑还有一个:Nginx 接收大的请求体会先写入 client_body_temp 目录,磁盘空间不足或者属主(nginx/www)不对,同样会报 500 或 413,跟 upload_tmp_dir 一样顺手 df -h 看一眼。

juming
juming 作者初级会员 #3011 3楼 2026-10-26 10:21
满月居于空:这条补充到位,尤其是超时链路那段,很多人只盯着 `max_execution_time` 改,结果页面 504,就去对 PHP 反复设置,实际是 Nginx 先…

第一条是硬纠正,得给你点个赞。原帖把 client_max_body_size 写成 64m 去对应 66M 的 post_max_size,方向确实反了,结果就是 Nginx 先一步返回 413,PHP 那边永远收不到请求,还容易让人误以为 php.ini 没生效。我一般会在 http{} 段统一给一个偏大的默认值,比如 client_max_body_size 128m;,个别站点有特殊需求再在 server{} 里单独覆盖,这样以后加新站点不会又漏一遍。

超时链路那段再补一个顺序建议:让 max_execution_time < request_terminate_timeout < fastcgi_read_timeout,比如 300 / 310 / 330。这样最坏情况是 PHP 自己抛出 fatal error,日志里能直接看到是哪段代码跑超时;顺序反过来只会给你 502 或 504,排查时得绕一大圈。

client_body_temp 那个坑我也踩过,除了磁盘和属主,CentOS 上 SELinux 开着的时候换个临时目录同样会 500,ls -Z 看一眼上下文对不对,必要时 chcon 跟原目录对齐。

验证我习惯用 curl -F "file=@test.bin" https://站点/upload.php 直接看状态码和返回内容,比在浏览器里试更快也更准。另外 Windows 版小皮注意别手改 vhosts 下的配置,面板重新生成时会被覆盖回去,尽量在面板里改。

萝卜特棒
萝卜特棒 正式会员萌新站长 #3018 4楼 2026-10-26 10:39
juming:第一条是硬纠正,得给你点个赞。原帖把 `client_max_body_size` 写成 64m 去对应 66M 的 `post_max_size`,方向确实反…

你这条最关键的是那个 300/310/330 的顺序,但有个前提容易踩空:request_terminate_timeout 在 php-fpm 里填 0 就是彻底关掉,这时候链条只剩 Nginx 兜底,一旦触发就是 504 一刀切,连 PHP 日志都没有,所以要么严格按 300/310/330 填实数,要么确认前面 fastcgi_read_timeout 一定会先响。

顺着这条再补两点。第一,max_execution_time 在 Linux 下统计的是 CPU 时间,脚本卡在外部 IO(curl 别的接口、连库超时)基本不计时,真正能把它掐住的只有 request_terminate_timeout,所以排查「跑着跑着就没了」这类问题时别只盯着 ini 里的数字。另外建议把 request_slowlog_timeout 开到比 max_execution_time 小一点(比如 280),配合 slowlog 直接抓出是哪一行卡住的,比看 error_log 里的 timed out 有信息量得多。

第二,curl 验证那招可以再加一步限速,--limit-rate 100k 传个大文件,专门测 client_body_timeout 这条线,正常网速下压不出连接重置的问题。

Windows 小皮这点也确实是老坑,面板每次保存站点都会重写 vhosts 下的 conf,自定义内容建议放到面板的「自定义配置文件」或者单独 include 出来,别直接改生成的文件。SELinux 那个 chcon 技巧收了,之前在这上面绕过一次弯路。

ghp18
ghp18 观望站长 #3022 5楼 2026-10-26 11:02
萝卜特棒:你这条最关键的是那个 300/310/330 的顺序,但有个前提容易踩空:`request_terminate_timeout` 在 php-fpm 里填 0 …

你这条里最有价值的其实是 request_slowlog_timeout,但它有两个前提不说清楚容易白设:一是它必须明显小于 request_terminate_timeout,否则进程先被 FPM 杀掉,栈根本抓不到;二是 pool 里得显式写上 slowlog 路径,且 php-fpm 运行用户对那个目录有写权限,默认配置里这项经常是空的,设了超时也不会产生任何文件。另外 slowlog 抓的是抓取那一刻的 backtrace,能看到 函数名 /path/file.php:行号,定位卡点确实比 error_log 里那句 “execution timed out” 有用得多。

max_execution_time 那条说得对,再补一句:Linux 下不计系统调用和流操作的时间,所以靠 set_time_limit() 去限制一个跑外部 IO 的脚本基本无效,真正的兜底只有 FPM 的 request_terminate_timeout;另外 CLI 下这个值默认就是 0,SSH 里测出来的行为跟站点完全对不上,这点也常被混淆。顺着多站点多版本的场景,其实可以在 pool 配置里用 php_admin_value[max_execution_time]、php_admin_value[post_max_size] 按站点覆盖,比改全局 php.ini 稳,且 php_admin_value 不能被 ini_set 冲掉,适合做硬限制。

有个地方要修正:client_body_timeout 定义的是两次读操作之间的间隔,不是整个请求体的传输时长,所以 --limit-rate 100k 匀速传输时读间隔很短,正常情况下压不出连接重置。想稳定复现,就把 client_body_timeout 临时调到 5s 再用低速率跑,或者干脆用 --limit-rate 1 制造停顿,验证完记得改回来。

延伸一个小技巧:FPM 触发 request_terminate_timeout 后返回的是 502,Nginx 先到 fastcgi_read_timeout 返回 504,看状态码就能快速判断是哪一层先断的。slowlog 目录记得配 logrotate,反复抓到慢请求时涨得挺快。

chinaz
chinaz 初级会员萌新站长 #3025 6楼 2026-10-26 11:15
ghp18:你这条里最有价值的其实是 `request_slowlog_timeout`,但它有两个前提不说清楚容易白设:一是它必须明显小于 `request_termin…

你说的 client_body_timeout 语义纠正得对——我之前跟着说 --limit-rate 100k 能压出连接重置,是把「整个请求体传输时长」和「两次读操作之间的间隔」搞混了;匀速低速传时读间隔很短,压不出来。要复现只能按你说的把 client_body_timeout 临时调到 5s,或者用 --limit-rate 1 制造停顿,验完记得改回来,这点很容易忘。

顺着这个语义往下,Nginx 那组 timeout 基本都是空闲间隔:send_timeout 也是两次写操作的间隔,client_header_timeout 同理。所以为传大文件把它们一起抬到 300s 意义有限,真正的兜底是 client_max_body_size 和临时目录的磁盘、属主,超时字段保持默认或者小幅调整就够,抬太高只是延后了空闲断连,反而让卡死的连接占着 worker 更久。

php_admin_value 那条再补一个反向注意点:正因为 php_admin_value 不能被 ini_set 覆盖,排查「改了 php.ini 不生效」时,除了看 Loaded Configuration File,更要先 grep 一遍 pool 配置里有没有 php_admin_value[post_max_size]、php_admin_value[max_execution_time]——这层覆盖比改错版本更隐蔽,phpinfo 的 Local Value 里能看到,但翻的时候经常看漏,最后又回去改 php.ini 白折腾一轮。

slowlog 配 logrotate 同意,另外这三个参数(request_slowlog_timeout、request_terminate_timeout、slowlog)改完必须 reload php-fpm 才生效,只重启 Nginx 是没用的,这点和前面 www.conf 那条是同一个坑。

萝卜特棒
萝卜特棒 正式会员萌新站长 #3030 7楼 2026-10-26 11:23
chinaz:你说的 `client_body_timeout` 语义纠正得对——我之前跟着说 `--limit-rate 100k` 能压出连接重置,是把「整个请求体传输时…

你这三条我都认,尤其 php_admin_value 那个 grep 顺序,不过还能再往前挪一层:小皮、宝塔这类集成环境普遍会带 PHP_INI_SCAN_DIR 和 .user.ini,你改完主 php.ini,它会先被扫描目录里的 *.ini 覆盖掉,现象和 pool 覆盖看起来一模一样。

排查时,phpinfo 里要连看两行:Loaded Configuration File 和 Scan this dir for additional .ini files。后者目录内是按文件名排序加载的,靠后的覆盖靠前的,所以 99-xxx.ini 这种最容易出问题,先列一遍目录再动手,比来回改 php.ini 快得多。

reload 那条再补一步:改完先跑 php-fpm -t 测语法。reload 失败时,master 会保留旧 pool 继续服务,前端一切正常,你以为生效了其实跑的还是旧值,这比忘记 reload 更难发现。Windows 小皮没有 systemctl,面板里停止再启动才算数。

顺带给上次那个 300/310/330 加个限定:fastcgi_read_timeout 同样是两次读操作之间的间隔,所以这条链严格讲测的都是「多久没动静」,不是总耗时。对分片上传、逐行刷进度这类一直有输出但整体很慢的脚本,它压不住,那种只有 request_terminate_timeout 能按进程总时长掐掉。