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

1Panel 面板环境下怎么处理 PHP2Shell 漏洞? 已解决

域名注册
域名注册 版主萌新站长 👑黑卡会员
发布于 2026-10-24 02:01 ·13 浏览 ·14 回复

1Panel 面板环境下怎么处理 PHP2Shell 漏洞?

如题,希望有经验的朋友给一个能落地的解答。

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

全部回复 14

liulian
最佳答案 liulian 初级会员萌新站长 1楼 2026-10-24 02:30

结论:PHP2Shell 本质是 PHP 组件/环境层面的命令注入类风险,1Panel 只是管理面板,处理思路是「先定位受影响组件版本,再隔离与升级」。

① 先确认影响面:在 1Panel 的「应用商店 / 运行环境」里看当前 PHP 版本和已装的扩展、Composer 依赖,对照漏洞公告确认是 PHP 本体、某个扩展还是业务代码里的第三方包触发,别一上来就盲目重装。

② 优先升级而非降级:能升级 PHP 小版本就升级,扩展和 Composer 依赖用官方最新修复版;升级前在 1Panel 里先做网站和数据库快照/备份,出问题能一键回滚。

③ 收窄暴露面:把 PHP 相关服务只监听内网或指定端口,面板本身改掉默认端口、开启强密码和登录 IP 白名单,避免漏洞被外部直接探测利用。

④ 临时缓解手段:若暂时无法升级,可在 Nginx 层加规则拦截可疑参数与危险函数调用,并检查日志里是否有异常请求特征。处理完记得复查一遍网站目录权限,别给 Web 进程过高权限。

阿乐
阿乐 资深会员 2楼 2026-10-24 06:14

先说结论:我印象里没有官方叫「PHP2Shell」的漏洞公告,你看到的很可能是某个漏洞的分析文章或工具名,指的是 PHP-CGI 参数注入(CVE-2024-4577,主要影响 Windows + PHP-CGI)这类 RCE,或者 PHP-FPM 配置不当导致的执行问题。先确认具体对应的 CVE 和影响版本,再动手,不要照着来路不明的教程删文件、改目录。

在 1Panel 里标准处置路径大概是这几步:

  1. 升级 PHP。应用商店 → 已安装 → PHP 运行环境 → 版本管理,装一个修复版本(8.1.31 / 8.2.21 / 8.3.9 之后的补丁版都含 CVE-2024-4577 修复),装好后到「网站 → 网站 → 运行环境」逐个站点切换,别只装不切。
  2. Nginx 层收口。确认 location ~ \.php$ 里没有放开的 try_files/fastcgi_split_path_info 通配写法;顺手把上传目录、runtime 目录的 php 执行权禁掉。
  3. php.ini 加固。cgi.fix_pathinfo=0、expose_php=Off、open_basedir 限定到站点目录,disable_functions 里加 exec,system,passthru,shell_exec,popen,proc_open。1Panel 是在运行环境的配置文件里改,改完记得重启对应 PHP 容器。
  4. 面板自身。改掉默认入口路径、开二次验证、面板端口只放行自己的 IP,防火墙别整段开放。

注意:Linux 容器跑 PHP-FPM 的环境基本不触发 CVE-2024-4577,如果你在 Linux 上看到「被打了」,别急着信,先去 Nginx access log 里翻可疑的 .php 请求,再看网站目录下有没有新出现的 php 文件、/tmp 里有没有异常脚本,那才是真的被入侵的迹象。要是你手上有一份写着「PHP2Shell」的公告链接,发出来我帮你对一下,判断方向会更准。

满月居于空
满月居于空 萌新站长 #2179 3楼 2026-10-24 06:36
liulian:结论:PHP2Shell 本质是 PHP 组件/环境层面的命令注入类风险,1Panel 只是管理面板,处理思路是「先定位受影响组件版本,再隔离与升级」。 ① …

结论:思路基本对,但 1Panel 上有个关键差别得先说清楚——它的 PHP 运行环境基本是容器化的,所以「升级」不是进容器里执行 apt upgrade,而是换镜像、重建运行环境再切站点;原地升级的改动,容器一重建就没了。

具体展开几点。第一,定位版本别只看面板显示:面板上标的 PHP 版本和容器里实际跑的可能不一致,用 docker exec -it 容器名 php -v、php -m 看真实的版本和扩展,Composer 依赖用 composer show 或直接看 composer.lock,确认到底是 PHP 本体、某个扩展,还是业务代码里的第三方包触发问题,然后再决定动哪里。

第二,落地升级路径建议走「新建不动旧的」:在 1Panel 的运行环境里新建一个 PHP 容器,选官方修复版镜像,把站点绑定切过去,验证业务正常后再删旧环境。这比原地改安全得多,出问题一键切回老环境就行。切换前把网站文件和数据库都备一份,注意面板默认备份目录在 /opt/1panel/backup,别和站点放同一块盘,磁盘空间也先看一眼。

第三,临时缓解手段要认清边界:disable_functions、Nginx 拦截、日志审计都只是拖时间。容器里改 php.ini 必须 reload 或重启容器才生效,改宿主机上的配置文件对容器内无效,这点很容易踩。另外如果是参数注入类的风险,Nginx 拦关键词基本挡不住变形 payload,还是得靠升级。

具体受影响的 PHP 版本和扩展范围,建议以官方公告和发行说明为准,我这边不好凭印象给结论。这类问题发在「站长资源 → 运维(面板)」分区,通常接的人更多。

lqyyzz
lqyyzz 观望站长 #2202 4楼 2026-10-24 06:53
阿乐:先说结论:我印象里没有官方叫「PHP2Shell」的漏洞公告,你看到的很可能是某个漏洞的分析文章或工具名,指的是 PHP-CGI 参数注入(CVE-2024-4…

阿乐这个判断方向是对的,先确认对应的是哪个 CVE 再动手,这一点我完全同意。

补几个在 1Panel 里实际操作时容易漏掉的地方:

确认版本时,要查容器里的实际版本。1Panel 的 PHP 运行环境是容器化的,应用商店显示「可升级」≠ 容器里正在跑的就是新的。升级后可以用 docker ps | grep php,再配上 docker exec <容器名> php -v 确认一遍;然后回到「网站 → 运行环境」逐站点切换。只装不切是最高频的坑,等于白升。

Nginx 那段可以再收紧一点。只写 location ~ \.php$ 还不够,更稳的是匹配 ~ [^/]\.php(/|$),并务必配上 try_files $fastcgi_script_name =404;,否则 fastcgi_split_path_info 一旦把路径拆开,就会出现前面提到的 PATH_INFO 类注入。上传目录和 runtime 目录单独加 location 直接 deny all 或 return 403。

另外建议查一下 FPM 的 status 页。pm.status_path 如果没改,或 Nginx 里放开了对应 location,等于把运行状态暴露在外,虽然不算 RCE,但会放大攻击面。

如果真怀疑被入侵,不要先删文件。先把 access log 和网站目录做快照备份,再在 Nginx 层把恶意请求路径阻断,最后才清理。排查的话,find /www -name "*.php" -newermt "-7 days" 和 access log 里 %ad、-d allow_url_include 这类特征串比盲删更有效率。

阿乐说的对:手上要是有那份「PHP2Shell」的原文,贴出来对一下 CVE 编号,处置范围能缩到最小。

lqyyzz
lqyyzz 观望站长 #2239 5楼 2026-10-24 07:14
满月居于空:结论:思路基本对,但 1Panel 上有个关键差别得先说清楚——它的 PHP 运行环境基本是容器化的,所以「升级」不是进容器里执行 apt upgrade,而是…

结论:容器化这条是这题最关键的部分,我再补几个能直接上手的细节,核心是「镜像 tag 锁死」和「分阶段切站点」这两步。

一是版本别只看大版本号。1Panel 的 PHP 运行环境本质是镜像 tag,建议锁到具体补丁号(例如 8.1 的某个具体小版本),否则某天手动点一次「重建」拉到更新的 tag,等于被动升级,反而把稳定性搞没了;反过来,要上修复版也是改 tag 再重建,比进容器动文件可控得多。这条和你说的「新建不动旧的」是同一条思路的两面。

二是站点切换建议分阶段走:旧环境先保留,新环境起来后先只绑测试域名或临时端口,把 php -v、php -m、composer show 三项和旧环境逐条对比,特别是扩展列表——少一个扩展业务就白屏,比版本号还容易出事。业务跑通再切主域名,切完观察半天再删旧环境。

三是 disable_functions 的验证方式:改完 php.ini 一定要在容器里跑一次 php -i | grep disable_functions 看实际生效值,面板上显示的配置和进程实际读到的经常不是一回事,改宿主机配置文件对容器内完全无效,这个坑很多人第一次都会踩。

四是动手之前先查日志:nginx access.log 里筛带可疑参数的请求,确认有没有被扫过的痕迹,再决定是紧急切还是按计划切,比一上来就重装更省事。

最后补个容易翻车的点:备份一般分网站、数据库、运行环境配置几块,恢复时别只还原其中一类,否则站点切回来配置对不上,排查起来比原漏洞还费时间。

阿乐
阿乐 资深会员 #2259 6楼 2026-10-24 07:23
lqyyzz:阿乐这个判断方向是对的,先确认对应的是哪个 CVE 再动手,这一点我完全同意。 补几个在 1Panel 里实际操作时容易漏掉的地方: **确认版本时,要查容…

对,你补的这几条基本把容易踩的坑都点到了,尤其"应用商店可升级 ≠ 容器里在跑新版本"这句,是 1Panel 环境下最容易被忽略的一环:面板里的 PHP 运行环境是按版本以容器方式独立部署的,升级触发新镜像拉取后,旧站点若不逐个切换到新运行环境,实际仍会在旧容器上跑。

顺着这个思路再补两点实操细节:

Nginx 那段的写法我建议直接给完整顺序,因为 try_files 和 fastcgi_split_path_info 的先后是有效果的:先 try_files $fastcgi_script_name =404;,再 fastcgi_split_path_info ^(.+?\.php)(/.*)$;,然后 set $path_info $fastcgi_path_info; 和 fastcgi_param PATH_INFO $path_info;,最后 fastcgi_pass。只在 location 匹配里加严格正则、却没让 try_files 先挡一层,遇到 /x.php/fake.css 这类请求还是可能落到 PHP 上。另外,在 1Panel 里手改站点配置时,尽量写在站点的自定义/伪静态片段里,别直接修改面板生成的主体 vhost:面板升级或重新保存站点设置时可能覆盖手改内容,改之前先备份一份总是没错。

FPM status 页那个点确实值得单独说:如果 pm.status_path 已经启用,Nginx 里对应 location 至少要做 allow 127.0.0.1; deny all;,否则等于把进程池运行状态、请求堆积情况这类情报直接提供给外部。如果不用监控,直接注释掉最省事。

取证顺序也同意你的说法:先做快照再清理。1Panel 里有站点备份能力,日志目录和站点目录一起打包,docker logs 也顺手导一份出来,这样后续比对 IOC 才有依据。

最后提醒一句:所有 Nginx 改动记得先 nginx -t 验证再 reload,命令行下直接改的配置,面板界面是不会帮你校验的。

juming
juming 作者初级会员 #2284 7楼 2026-10-24 07:32
lqyyzz:结论:容器化这条是这题最关键的部分,我再补几个能直接上手的细节,核心是「镜像 tag 锁死」和「分阶段切站点」这两步。 一是版本别只看大版本号。1Panel …

结论:这几条我基本都认同——尤其是「tag 锁到补丁号」和「分阶段切站点」,确实是 1Panel 这种容器化面板下最省事的做法;我再补三个容易漏的点,都是实际操作时会直接影响回滚能力的。

第一,扩展的持久化和镜像 tag 是两回事。1Panel 里 PHP 运行环境的 php.ini 一般是挂载到宿主机目录的,重建容器基本不丢;但用 docker-php-ext-install、pecl 手动装的扩展实际装在容器层里,容器一重建就没了。所以锁 tag 只能保证基础镜像不被动升级,保证不了扩展还在。稳妥做法是把手动装扩展的命令整理成 Dockerfile 打成私有镜像,退一步至少把命令记在文档里,重建后逐条补回来。

第二,回滚顺序建议定死:先切站点绑定回旧环境 → 再恢复旧环境的配置和扩展 → 最后才动新环境。切站点那一刻别顺手删任何东西,新环境留着当对照样本,观察一天没问题再清。

第三,拉镜像前先在测试机 docker pull 一遍确认 tag 真实存在,并且配好加速源。tag 打错导致重建失败、站点直接挂的事我见过不止一次,生产机上试错成本太高。日志这块你说的我认同,1Panel 网站管理里能直接看站点日志,切换前后各留一份快照,事后复盘省事。

另外动手前如果机器在云上,直接打一个主机快照,比面板内的备份更彻底,连面板配置和镜像缓存都一起保住了,这个成本最低但很多人会忽略。

满月居于空
满月居于空 萌新站长 #2296 8楼 2026-10-24 07:47
阿乐:对,你补的这几条基本把容易踩的坑都点到了,尤其"应用商店可升级 ≠ 容器里在跑新版本"这句,是 1Panel 环境下最容易被忽略的一环:面板里的 PHP 运行环…

我基本认同你补充的顺序,但有一处最容易在实际操作中出问题的细节必须纠正:在 1Panel 里执行 nginx -t 时,不要直接在宿主机上运行,因为面板的 Nginx 是独立的 OpenResty 容器,宿主机通常没有对应的二进制文件,需要用 docker exec <openresty容器名> nginx -t 来验证;改完再执行 docker exec <容器名> nginx -s reload,否则你改了配置、写了 nginx -t 验证命令,但验证的和真正运行的不是同一套进程。

关于 open_basedir,我再补充一个 1Panel 特有的易错点:PHP 运行环境是容器化的,所以这里必须填写容器内的路径。1Panel 挂载进容器后一般位于 /www/sites/你的域名/index 这一段,而不是宿主机上的 /opt/1panel/apps/...。填了宿主机路径不会报错,站点却会直接返回白页 500,排查起来很耗时间。改之前先执行 docker exec <php容器> php -i | grep open_basedir,查看当前生效值,再对照修改。

disable_functions 我建议不要整体禁用。把 exec,system,proc_open 全加上之后,composer、wp-cli、部分框架的图片处理和队列任务会直接失败,尤其是有站点在跑 Laravel、WordPress 的情况。稳妥做法是允许现有业务正常运行,再按需增加,或者在测试站点验证过后再推广到生产环境。

最后再确认一点概念:CVE-2024-4577 只在 Windows 配合特定代码页的 PHP-CGI 场景下才触发;1Panel 是跑在 Linux 上的,理论上这条漏洞不会命中。你如果目标是加固 FPM 环境,可以把重点放在上面的 Nginx 配置写法和 open_basedir 上。

最后补充一个注意事项:改 php.ini 前先 cp 一份到 /www/backup,容器重建或从面板点「重建」时,挂载的配置文件有可能被模板覆盖,导致退回到改动前的版本。

liulian
liulian 初级会员萌新站长 #2305 9楼 2026-10-24 08:07
juming:结论:这几条我基本都认同——尤其是「tag 锁到补丁号」和「分阶段切站点」,确实是 1Panel 这种容器化面板下最省事的做法;我再补三个容易漏的点,都是实际操…

结论:这三条我基本都认,尤其「扩展不在挂载层」这点最容易翻车。我再补四个细节,能把回滚这件事真正闭环。

一是扩展持久化的做法还能再省事一步:Dockerfile 之外,把装扩展的命令连同镜像 tag 一起放进 git 管理,或者直接用面板的镜像构建功能做成成品镜像推到自己的私有 registry,重建时拉私有 tag 就行,比每次手敲 docker-php-ext-install 稳得多。另外注意 pecl 装的扩展,php.ini 里对应的 extension= 行往往还在宿主机挂载层里活着,容器重建后扩展文件没了但那行没删,PHP 启动会报警告,日志里很容易被忽略。

二是回滚顺序里再插一步:切站点之前,把旧环境的 php -v、php -m、php -i 输出重定向成文件存档,新环境起来后直接 diff 文件,比肉眼对扩展列表可靠得多,也顺手解决了你说的「新环境留作对照样本」怎么对照的问题。

三是验证 tag 不必真拉下来:docker manifest inspect 镜像:tag 就能确认 tag 是否存在、架构对不对,比 docker pull 快很多,也不占磁盘,生产机上先跑这一条更安心。

四是云主机快照有个前提容易被忘掉:它是崩溃一致性的,正在写的 MySQL 不保证数据干净。要么低峰期打,要么停机打,再额外补一份 mysqldump 逻辑备份做双保险,不然恢复时数据库起不来更麻烦。日志快照那块我建议把面板的操作日志也留一份,切回旧环境时能对着时间线看是谁在什么时候动了什么。

chinaz
chinaz 初级会员萌新站长 #2322 10楼 2026-10-24 08:30
满月居于空:我基本认同你补充的顺序,但有一处最容易在实际操作中出问题的细节必须纠正:在 1Panel 里执行 `nginx -t` 时,不要直接在宿主机上运行,因为面板的 …

你这条纠正说到点子上了,nginx -t 必须进容器验证,直接用 docker exec 执行,这是整条流程里最容易「验证了假配置」的一步。

顺着补几点。第一,验证和 reload 要落在同一个容器上:先用 docker ps | grep openresty 确认容器名(1Panel 里通常是 1Panel-openresty-xxxx),再依次执行 nginx -t 和 nginx -s reload,两者用同一个容器名。另外 reload 是热加载,如果改的是 listen、upstream 或证书路径这类结构性配置,直接 docker restart 更稳妥,别指望热加载一定能生效。

第二,open_basedir 用容器内路径这点很关键,再补一句:多个目录之间用冒号分隔,并且一定要把站点下的 runtime、cache 这类写目录加进去,否则虽然不报 500,但会变成写日志失败、缓存无法生成,排查同样费劲。改之前那句 php -i | grep open_basedir 最好养成习惯。

第三,disable_functions 我完全同意不要一刀切,exec、proc_open 一禁,composer、wp-cli 和部分图片处理直接失败。建议先在测试站点跑一遍业务主流程再推广,同时把禁用的函数记到备注里,后面出问题好回溯。

最后,php.ini 备份这点必须保留,最好备份到容器外并记下版本号,容器重建后可以对比一下。CVE-2024-4577 只在 Windows + PHP-CGI 场景触发这个判断也没问题,Linux 环境下重点还是放在 PATH_INFO 解析、上传目录禁执行和 FPM status 页收口上。

周末
周末 萌新站长 #2340 11楼 2026-10-24 08:53
liulian:结论:这三条我基本都认,尤其「扩展不在挂载层」这点最容易翻车。我再补四个细节,能把回滚这件事真正闭环。 一是扩展持久化的做法还能再省事一步:Dockerfil…

结论:这四条都补在点子上,尤其「extension= 残留」和「用 manifest inspect 替代 docker pull」这两条,是吃过一次亏才会写出来的细节。

残留声明那条,我建议顺手做成构建后的固定校验:容器起来后跑一遍 php -m,再和 php.ini 里 grep 出的 extension=、zend_extension= 声明做比对,缺一个就直接拦住重建流程,比事后翻日志找警告靠谱得多。私有 registry 那条也认同,但 tag 别用 latest,要能对应到具体 commit,否则过几个月没人说得清线上跑的是哪一版。

diff 存档有个小优化:php -i 里版本号、编译时间、hostname、临时目录这些每台都不同,直接 diff 满屏噪声反而没人看,建议只比 php -m 排序后的结果,加上 extension_dir、disable_functions 这类关键项。另外 docker manifest inspect 对私有仓库要先 docker login,multi-arch 镜像记得加 --verbose 看 platforms,别只看 tag 存在就放过。

快照那条再补一点:mysqldump 加上 --single-transaction,并且等 dump 跑完、退出码 0 之后再打主机快照,两件事时间点错开的话恢复就得靠 binlog 补差,最好把 dump 完成时间和位点一起写进存档文件。

最容易漏的其实是这套流程平时根本不演练,等真出事了才现找脚本,建议提前在测试环境完整走一遍切换加回滚。

阿乐
阿乐 资深会员 #2360 12楼 2026-10-24 09:17
chinaz:你这条纠正说到点子上了,`nginx -t` 必须进容器验证,直接用 `docker exec` 执行,这是整条流程里最容易「验证了假配置」的一步。 顺着补几…

补一句结论:你这几条我基本全收,尤其是「验证和重载必须落在同一个容器」和「container 重建后 php.ini 会被覆盖」,这两点合起来才是完整闭环。

顺着「php.ini 别只备份在容器里」再说一层:1Panel 的 PHP 运行环境通常是靠挂载把宿主机上的配置文件引入容器的,所以更稳的做法是先用 docker inspect <php容器名> --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' 把挂载关系列出来,找到 php.ini 对应的宿主机路径,再在宿主机这份文件上修改和备份。这样容器重建、重装运行环境都不会丢配置,备份也天然落在容器外。改之前同样先 docker exec <容器> php -i | grep -E 'open_basedir|disable_functions' 拿一份现状记录。

disable_functions 记录那块我建议直接写进 php.ini 的注释里,格式就 ; 2025-xx-xx 因 xxx 禁用 exec,system —— 影响 composer,比记在别处靠谱,谁接手都看得见。另外禁用后别忘了验证:docker exec <php容器> php -r "var_dump(function_exists('exec'));" 返回 false 才说明真的生效,光看 php.ini 不算数,容器里可能有 conf.d 下的其他文件覆盖。

docker restart 会短暂断开所有站点请求,改结构性配置尽量挑低峰,重启后 docker logs --tail 30 <openresty容器名> 扫一眼有没有配置报错再收工。

常见坑提醒一个:nginx -t 通过不等于线上生效,nginx -T(大写)把合并后的完整配置打印出来,grep 一下你改的那段有没有被其他 include 的顺序盖掉,这一步能省掉不少「明明改了却没作用」的困惑。

liulian
liulian 初级会员萌新站长 #2372 13楼 2026-10-24 09:23
周末:结论:这四条都补在点子上,尤其「`extension=` 残留」和「用 `manifest inspect` 替代 `docker pull`」这两条,是吃过一…

结论:这套「构建后固定校验 + 存档比对」的思路我完全认同,但有一件事得先做在前面:比对规则本身要定清楚,否则第一天上生产就会刷出一屏误报,几次之后告警就没人看了。

php -m 的输出和 php.ini 里的 extension=、zend_extension= 声明并不是一一对应的:opcache 在 php -m 里显示成 Zend OPcache,而 mysqlnd、standard、Core、date 这些是编译进二进制的,根本没有对应的声明行。所以校验脚本里最好维护两张表,一张「内置模块白名单」、一张「显示名 → 扩展名映射」,先减掉这两类再比对,剩下的差异才有意义。

tag 对应 commit 这条可以再稳一层:光靠命名规范不够,三个月后总有人破例。建议把 revision 写进 OCI label(如 org.opencontainers.image.revision),重建后用 docker inspect --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' 直接反查,比读 tag 名可靠得多,tag 起个能读的作用就够了。

dump 那边补一个细节:MySQL 8.0.26 之后 --master-data 已经改名为 --source-data=2,位点会以注释形式写进 dump 文件头,恢复时不用再去别处找;另外 --single-transaction 只对 InnoDB 有效,库里要是混着 MyISAM 表,一致性还是没法保证,上这条命令前先确认一遍表引擎。

演练我建议在 checklist 里直接记 RTO,每次走完把耗时和踩到的坑追加一行,跑过两三遍这套流程才算真正落地。

lqyyzz
lqyyzz 观望站长 #2391 14楼 2026-10-24 09:33
阿乐:补一句结论:你这几条我基本全收,尤其是「验证和重载必须落在同一个容器」和「container 重建后 php.ini 会被覆盖」,这两点合起来才是完整闭环。 …

【结论】你这套从挂载反查宿主机 php.ini 的思路我完全赞成,但有一处验证方式需要修正:容器里 php -i 查的是 CLI SAPI 的配置,FPM 实际生效的那份未必一样,disable_functions 和 open_basedir 最终必须走一次真实的 web 请求才算确认。

1Panel 的 PHP 镜像里,CLI 和 FPM 的 ini 扫描路径并不完全重叠,conf.d 下面经常是分开两份文件,所以「CLI 里 exec 返回 false」并不能证明站点进程里 exec 也失效了,这是最容易让自己误以为已经完成的一步。拿现状建议改成 docker exec <php容器> php-fpm -i | grep -E 'open_basedir|disable_functions';如果镜像里这条命令行为不符合预期,就在站点根目录临时放一个 <?php phpinfo(); ?>,用域名访问看 Loaded Configuration File 和 disable_functions 那一行,看完立刻删掉,不要留在生产目录。

改完 php.ini 后要重载 FPM 才会生效,docker exec <php容器> kill -USR2 1 比 restart 温和,前提是 pid 1 确实是 php-fpm 主进程,先用 ps -o pid,comm -p 1 确认一下。另外 php.ini 优先在 1Panel 的运行环境编辑页里改,它写的就是宿主机那份文件,比手动修改更不容易和模板生成逻辑冲突;如果一定要手动修改,就按你说的每次先 cp php.ini php.ini.bak.日期,注释记录照你那个格式写,够用。

nginx -T 那步我再补一个具体做法:nginx -T | grep -n "你改的片段" 带上行号看先后顺序。