本文约 3,420 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:一次 PHP 升级,收益和风险都很大
从 PHP 7.4 升到 8.2,WordPress 的执行效率通常有 20%~40% 的提升,同时 7.4 已停止安全支持,继续用等于裸奔。
但升级也是最容易”一把搞挂站点”的操作。我见过最典型的情形:运维在面板里点了一下切换 PHP 版本,前台立刻白屏,而备份是三天前的。
原理分析:为什么升级会挂
PHP 大版本升级会做三件事:
- 移除废弃特性(PHP 8.0 移除了大量 7.x 弃用的函数与语法);
- 改变错误处理级别(8.0 起很多 warning 升级为 TypeError/Error);
- 收紧类型检查(动态属性、参数类型、字符串与数字比较的行为变化)。
WordPress 核心本身早就支持 PHP 8.x,出问题的基本都是第三方插件和主题,尤其是三四年没更新的商业插件、自己写的函数、以及用了 create_function()、each()、动态属性这类老写法的代码。
保姆级实操:七步检查清单
第一步:先摸清当前环境
php -v
wp core version
wp plugin list --fields=name,version,update,status
wp theme list --fields=name,version,update,status
把插件主题列表导出成文件留档,升级后对比。
第二步:核对兼容性
逐个插件去官方目录页看 “Compatible with WordPress / PHP” 信息;商业插件看更新日志里有没有 “PHP 8.x support”。
更快的办法是批量扫代码里的高危写法:
cd wp-content
grep -rn "create_function" --include="*.php" . | head
grep -rn "\beach(" --include="*.php" . | head
grep -rn "mysql_query\|mysql_connect" --include="*.php" . | head
grep -rn "curly brace" --include="*.php" . 2>/dev/null | head
只要命中,那个插件基本在 PHP 8 下会出问题。
第三步:确认 PHP 扩展齐全
升级 PHP 版本后,扩展不会自动继承,这是最常见的失误:
php -m | grep -Ei "mysqli|mbstring|curl|gd|imagick|intl|zip|opcache|redis|bcmath|exif|fileinfo"
对比升级前的 php -m 输出,缺什么装什么:
sudo apt install -y php8.2-mbstring php8.2-curl php8.2-gd php8.2-intl \
php8.2-zip php8.2-imagick php8.2-bcmath php8.2-redis
少装 mbstring 会导致后台中文乱码,少装 fileinfo 会导致主题安装失败。
第四步:在测试环境先跑一遍
最稳妥的方式是克隆一份站点:
cp -a /var/www/mimangfei.com /var/www/test-mimangfei
mysqldump -u root -p wordpress | mysql -u root -p wordpress_test
# 改测试站 wp-config.php 指向测试库
wp --path=/var/www/test-mimangfei search-replace 'https://mimangfei.com' 'https://test.mimangfei.com' --all-tables --precise
然后给测试站单独配一个 PHP 8.2 的 PHP-FPM 池和 Nginx server 块,跑一遍核心页面。
没有测试环境的话,至少用 PHP 兼容检查工具扫一遍:
composer require --dev phpcompatibility/php-compatibility
./vendor/bin/phpcs -p wp-content --standard=PHPCompatibility --runtime-set testVersion 8.2-
第五步:开启调试日志再切换
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
这样即使前台白屏,你也能从 debug.log 看到是哪个文件的哪一行。
第六步:切换版本
宝塔:软件商店 → PHP-8.2 → 站点 → 切换 PHP 版本。
命令行(Ubuntu,多版本共存):
sudo update-alternatives --set php /usr/bin/php8.2
# Nginx 站点配置改 fastcgi_pass
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
sudo systemctl restart php8.2-fpm && sudo nginx -t && sudo systemctl reload nginx
第七步:切换后立即验证
wp core version
wp plugin list --status=active
tail -f wp-content/debug.log
手工检查:前台首页 / 内页 / 分类页、后台文章编辑页、媒体库上传、联系表单提交、支付或订单流程(如有)。
常见不兼容报错与对应原因
| 报错 | 原因 | 处理 |
|---|---|---|
Fatal error: Uncaught Error: Call to undefined function create_function() |
该函数 PHP 8.0 已移除 | 改插件或换插件 |
Deprecated: Dynamic properties are deprecated |
PHP 8.2 弃用动态属性 | 在类中声明属性 |
Fatal error: Uncaught TypeError: ... |
参数/返回类型不匹配 | 修正函数签名 |
Deprecated: Passing null to parameter |
8.1 起禁止 null 传给非 nullable 参数 | 加默认值或判空 |
Warning: Undefined array key |
8.0 起 notice 升级为 warning | 加 isset 判断 |
常见踩坑与失败案例
- 切换后扩展丢失 —— 装了 PHP 8.2 但没装 8.2 版的扩展,
wp命令直接报 “missing mysqli”。 - 案例:某站在面板切换 PHP 8.2 后前台白屏,查日志是某个 2019 年的商业主题用了
create_function()。处理方式:临时切回 7.4,联系主题方拿补丁,拿不到就换主题。 - OPcache 缓存了旧的 opcode —— 切换后仍报旧错误,执行
sudo systemctl restart php8.2-fpm或wp cache flush。 - 计划任务失败 —— 系统 cron 里写的是
/usr/bin/php7.4,切版本后要同步修改。 - 切换后内存占用上升 —— PHP 8 本身更省内存,如果反而上升,多半是某个插件在报错重试。
总结
PHP 升级的收益明确,风险也可控,关键是别在生产环境直接点切换。标准流程是:导出插件清单 → 扫高危写法 → 确认扩展 → 测试环境验证 → 开调试日志 → 切换 → 全面验收 → 保留回滚路径(旧 PHP 版本别急着卸载)。走完这套流程,升级基本不会出事,即使出事也能在几分钟内定位到具体插件。
