综合 PHP 8.2 安全支持到 2026-12-31 结束:并行装 8.4、影子端口验证、一条命令回滚

2026-10-01 20:01:32

PHP 8.2 安全支持到 2026-12-31 结束:并行装 8.4、影子端口验证、一条命令回滚

PHP 8.2 的安全支持将在 2026 年 12 月 31 日结束。本文梳理升级到 8.4 或 8.5 的完整路线:现状盘点、扩展清单导出、目标版本选择依据、并行安装而非覆盖升级、影子端口验证、切换后的九项验收清单,以及一条命令即可完成的回滚方案。

PHP 分支都会走完「两年活跃支持 + 两年安全支持」的四年周期。大量仍在运行的 WordPress、LNMP 与自研 PHP 站点,最后一次认真处理 PHP 版本还是 7.x 时代,之后一直靠发行版仓库里的默认版本维持。

PHP 从 7.x 到 8.x 不是一次小版本跳变。它改变了错误处理模型(大量警告升级为致命错误)、收紧了类型系统(内部函数参数校验变得严格)、移除了若干长期废弃的扩展与函数,默认配置也发生变化。升级失败通常不是因为某个函数被删掉,而是因为站点在流量高峰时才第一次触发那条代码路径。

本文讨论的是「怎么在可控的停机窗口内完成这次升级并保留回滚能力」。

先看结论

  • 先确认「到底在跑哪个 PHP」。不要相信面板显示,执行 php -v、php-fpm -v、ls -l /etc/alternatives/php 三条命令交叉验证,CLI 与 FPM 可能指向不同版本。
  • PHP 8.2 安全支持止于 2026-12-31;8.3 到 2027-12-31,8.4 到 2028-12-31,8.5 到 2029-12-31(以 php.net 支持版本表为准)。
  • 目标版本优先选 8.4 或 8.5,而不是只升到 8.3。8.3 活跃支持已结束。
  • 升级前必须导出完整扩展清单:php -m 与 php-fpm -m 各存一份。跨大版本升级最常见的翻车原因是扩展在新版本下没有对应包,或需要重新编译。
  • 代码兼容性扫描必须在改动服务器之前完成。
  • 生产变更前无条件备份三样:站点文件、数据库、PHP 配置目录(/etc/php/ 或 /etc/php.d/)。
  • 保留旧版本二进制并让 Nginx 与 FPM 的 socket 路径可切换,是实现「一条命令回滚」的前提。覆盖安装则没有回滚能力。
  • 升级后必须验证的不只是首页:定时任务、后台管理、表单提交、邮件发送、图片上传与缩略图生成、支付/回调类接口。

先确认现状:你究竟在跑什么

典型场景:系统里同时存在发行版自带的 PHP、手动编译的 PHP、以及某个面板(宝塔、aaPanel、OLS 一键包)自带的 PHP,三者 php.ini 与扩展目录各不相同。

# 1. 所有 PHP 二进制与版本
for b in php php-fpm php-cgi lsphp; do
  command -v "$b" >/dev/null 2>&1 && echo "$b -> $($b -v 2>/dev/null | head -1)"
done
# 2. alternatives 指向
ls -l /etc/alternatives/php* 2>/dev/null
# 3. FPM 实际在监听的 socket / 端口
ss -lntp 2>/dev/null | grep -i php
ls -l /run/php/ 2>/dev/null
# 4. 扩展清单(CLI 与 FPM 分开导出)
php -m > /root/php-ext-cli-$(date +%F).txt 2>/dev/null
php-fpm -m > /root/php-ext-fpm-$(date +%F).txt 2>/dev/null
wc -l /root/php-ext-*.txt

关键判据:ss -lntp 输出的 socket 路径必须与 Nginx 配置里 fastcgi_pass 的值完全对应。很多「改了 PHP 版本但站点没变化」的情况,本质是 Nginx 仍指向旧版本的 socket 文件。php --ini 给出的路径不一定等于 FPM 使用的路径,FPM 的配置在 /etc/php/<版本>/fpm/php.ini(Debian 系)或 /etc/php.ini + /etc/php.d/(RHEL 系)。

兼容性风险:8.x 真正会打断你的地方

第一类:警告变致命。 PHP 8 把许多以前只记一条 notice 就继续跑的情况改成抛错,例如访问未定义数组键、对 null 调用字符串函数、把非法值传给内部函数参数。只在你真正执行到那行代码时才出现,一个只在月末对账时才跑的管理页面可能升级后三周才第一次爆。

第二类:内部函数参数校验变严格。 传错类型会直接抛 TypeError,大量老代码依赖 strlen(null) 返回 0 这类隐式行为。

第三类:扩展与依赖缺位。 常见缺口是 mcrypt(已移除,需迁到 openssl 或 sodium)、旧版 gd 与 imagick 的编译差异、商业扩展没有对应新版本构建。

第四类:框架与 CMS 版本滞后。 应用代码兼容但框架版本不支持新 PHP。

静态扫描优先于人工阅读:

php -d memory_limit=1G /path/to/php-compatibility-checker --target-version 8.4 /var/www/your-site.test > /tmp/compat-report-84.txt 2>&1
grep -oE '^[^:]+' /tmp/compat-report-84.txt | sort | uniq -c | sort -rn | head -30

Composer 站点:

composer outdated --direct
composer check-platform-reqs

实操判据:扫描结果里命中数最多的 5 个文件,通常就是升级后最先报错的文件。

选择目标版本

8.2 安全支持截止 2026-12-31(仅过渡);8.3 2027-12-31;8.4 2028-12-31(推荐);8.5 2029-12-31(新项目或已验证兼容)。

判断原则:如果扩展或商业组件在 8.4 上还没有可用构建,就停在 8.3;否则直接上 8.4。不建议从 7.x 直跳 8.5。

操作路线:并行安装而非覆盖升级

Debian/Ubuntu 用 sury(deb.sury.org)源可并行安装多个 PHP 版本;RHEL 系用 Remi 源配合 dnf module。

CURRENT_PHP="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')"
echo "current: $CURRENT_PHP" | tee /root/php-upgrade-baseline.txt
apt-get install -y apt-transport-https lsb-release ca-certificates curl
apt-get update
apt-get install -y php8.4-fpm php8.4-cli php8.4-mysql php8.4-mbstring \
  php8.4-curl php8.4-xml php8.4-zip php8.4-gd \
  php8.4-intl php8.4-opcache php8.4-redis
php8.4 -v
ls -l /run/php/

扩展清单必须逐个对照第 1 步导出的 php-ext-fpm-*.txt。漏装扩展的后果不是报错,而是功能静默缺失——缺 intl 时日期格式化结果不同,缺 gd 时缩略图不再生成但页面照常返回 200。

影子端口验证(先不要改 Nginx)

cat >/etc/nginx/conf.d/php84-test.conf <<'NGINX'
server {
  listen 8081;
  server_name _;
  root /var/www/your-site.test;
  index index.php;
  location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}
NGINX
nginx -t && systemctl reload nginx
curl -sI -H 'Host: your-site.test' http://127.0.0.1:8081/ | head -5

切换、验证与回滚

tar czf /root/nginx-conf-$(date +%F-%H%M).tar.gz /etc/nginx/
sed -i 's#/run/php/php8.2-fpm.sock#/run/php/php8.4-fpm.sock#' /etc/nginx/conf.d/your-site.test.conf
nginx -t && systemctl reload nginx
systemctl status php8.4-fpm --no-pager | head -5
# 回滚
sed -i 's#/run/php/php8.4-fpm.sock#/run/php/php8.2-fpm.sock#' /etc/nginx/conf.d/your-site.test.conf
nginx -t && systemctl reload nginx

绝对不要在验证通过前卸载旧版本。切换后按清单逐项验证:首页与关键内页 200 且无 PHP 警告;后台可登录;表单提交成功;图片上传且缩略图正常生成;邮件发送正常;定时任务正常;日志无新增致命错误 grep -i 'PHP Fatal' /var/log/php8.4-fpm.log;OPcache 已启用;浏览器无 500/502。生产务必确认 display_errors 关闭、log_errors 打开。

升级后常见故障与判断顺序

现象一:全站 502,Nginx 日志 connect() to unix:... failed。 检查 systemctl is-active php8.4-fpm、ls -l /run/php/php8.4-fpm.sock、grep -rn 'fastcgi_pass' /etc/nginx/ | grep -i php。常见原因是 listen 配置与 Nginx 指向文件名不同,或 socket 属主与 Nginx worker 用户不一致。

现象二:页面能开但局部功能失效且无报错。 对比扩展差异:diff <(php8.2 -m | sort) <(php8.4 -m | sort) | grep '^<' | sort,^< 开头就是旧有新无的模块。

现象三:后台或某个插件致命错误、前台正常。 几乎总是插件自身兼容问题,先禁用恢复可用再离线处理。

现象四:性能下降。 先确认 OPcache 是否启用:php8.4 -i | grep -E 'opcache.enable|opcache.memory_consumption|opcache.max_accelerated_files';新版本 php.ini 是独立文件,很可能没沿用旧 OPcache 配置。

现象五:站点整体正常但搜索结果异常。 用爬虫 UA 抽查关键入口:

for u in "/" "/en/" "/sitemap.xml" "/robots.txt"; do ... curl -A "Mozilla/5.0 (compatible; Googlebot/2.1)" ... done

收尾

固定版本策略;把兼容性扫描接进 CI;记录本次变更(升级前后版本、扩展差异、改过的配置、命令、验证结果与回滚步骤);保留旧版本一到两周再清理。

官方资料

原文链接:https://www.mf8.biz/en/blogs/php-8-2-eol-upgrade-guide

复制全文 生成海报 PHP PHP-FPM 运维 升级迁移 Nginx

推荐文章

程序员茄子在线接单