没有不值得去解决的问题,也没有不值得去学习的技术!

OneinStack 生产环境将 PHP 8.1.19 升级到 PHP 8.5.9:Imagick 编译失败与 WordPress 多域名缓存验收

**Alt:** WordPress 生产环境完成 PHP 8.5.9 升级,终端显示 OPcache、Imagick、Redis、Nginx、WordPress 版本及中英文站和后台域名均正常返回 HTTP 200

作者:

,

WordPress 性能优化手记

如 如图1 所示,站点健康直接提示这是一个可能对性能或安全性产生重大影响的问题,需要优先解决。

(1) 从站点健康警告到全绿通关

PHP Fatal error: Uncaught RedisException: OOM command not allowed when used memory > 'maxmemory'. in /data/wwwroot/.../wp-content/plugins/w3-total-cache/Cache_Redis.php:150

(2) 解决 WordPress + Polylang 批量处理标签时遇到的 Redis OOM 错误

采用 ondemand 模式,适合 1 核小内存机器,空闲时释放进程。最终配置如下:如图4

(3) 一次WordPress站点504错误的排查与优化实录

优化前最终基准数据:历史累计504错误129条(6月3日峰值126条,为爬虫批量爬标签导致)。

(4) 从单日126次504超时到彻底稳定:WordPress 1核2G服务器极限优化全记录(附全部实操命令)

WebPageTest 核心指标

(5) WordPress性能基准测试与CDN选型实录:从国内拨测到海外WebPageTest,1核2G服务器如何面向全球

页面底部提示“此响应不是合法的 JSON 响应”。

(6) WordPress 标签保存失败?Nginx 限流规则惹的祸 —— 一次完整的 429 问题排查与解决

表示页面仍然是动态生成,没有缓存命中。

(7) WordPress + Nginx + W3 Total Cache 缓存未生效排查全过程(OneinStack 实战)

图7:带 Query String 后,W3TC 显示 Requested URI contains query

(8) WordPress CPU 再次满载:动态参数如何穿透 CDN 与 W3TC 页面缓存

图1:阿里云 ECS 在 14:33~14:42 期间 CPU 使用率持续接近 100%,而内存使用率整体较为稳定

(9) WordPress 服务器 CPU 再次满载:从 Nginx 499、PHP-FPM、Redis 到 W3TC 冷缓存的完整排查

图4:W3TC 最终使用 300 秒 × 7 页,并切换到中英文联合 Sitemap

(10) 从 CPU 告警到双域名预缓存:W3 Total Cache、EdgeOne 与 Cloudflare 96 小时缓存优化实战

WordPress 所有归档模板中使用 Language Visibility 和 WPCode Shortcode 添加中英文 Adsterra 广告

(11) WordPress 三域名架构再次踩坑:Adsterra 归档广告不生效,最终定位到 W3TC Object Cache

WordPress 多语言多域名缓存排查:修复 Polylang + W3 Total Cache 跨 Host 缓存失效问题

(12) WordPress 多语言多域名缓存排查:修复 Polylang + W3 Total Cache 跨 Host 缓存失效问题

WordPress 多域名环境下中文文章详情页未显示 Polylang 语言切换器

(13) WordPress 多域名下 Polylang 语言切换器延迟:W3TC Redis 跨 Host 缓存排查记录

图8:选择 2 核 4 GiB 后显示的实际补差价、2 Mbps 带宽和重启选项

(14) 从 CPU 再次告警到 ECS 升配:WordPress 服务器从 1 核 2G 升级到 2 核 4G 实录

**Alt:** WordPress 生产环境完成 PHP 8.5.9 升级,终端显示 OPcache、Imagick、Redis、Nginx、WordPress 版本及中英文站和后台域名均正常返回 HTTP 200

(15) OneinStack 生产环境将 PHP 8.1.19 升级到 PHP 8.5.9:Imagick 编译失败与 WordPress 多域名缓存验收

一、升级背景

我的 WordPress 生产环境运行在阿里云 ECS 上,使用 OneinStack 部署 Nginx、PHP-FPM 和 Redis。

当前网站不是普通的单域名 WordPress,而是由多个域名共同访问同一个 WordPress 安装:

Plaintext
中文站:https://www.shuijingwanwq.com
英文站:https://en.shuijingwanwq.com
后台域名:https://admin.shuijingwanwq.com
媒体域名:https://media.shuijingwanwq.com

其中:

  • Polylang 根据不同域名识别语言;
  • W3 Total Cache 提供 Page Cache 和 Object Cache;
  • Object Cache 使用 Redis;
  • 中文站接入 EdgeOne;
  • 英文站接入 Cloudflare;
  • 后台通过独立的 admin 子域名访问。

在正式升级之前,我先对服务器中的主要软件版本和升级顺序进行了整理。相关背景可以参考上一篇记录:

上一篇关于服务器软件版本与升级顺序的记录

当时确认的主要版本包括:

Plaintext
操作系统:Alibaba Cloud Linux 3
WordPress:7.0.2
Nginx:1.24.0
PHP:8.1.19
Redis 服务端:7.0.11
W3 Total Cache:2.10.3
Polylang:3.8.6

最终决定不同时升级所有组件,而是先处理 PHP。

原因很简单:PHP 直接影响 WordPress、插件、WP-CLI、PHP-FPM 和扩展兼容性。如果同时升级 Nginx、PHP 和 Redis,出现问题后很难快速判断到底是哪一层发生了变化。

因此,这一轮只将 PHP 从 8.1.19 升级到 8.5.9,Nginx 和 Redis 服务端留到后续分别处理。


二、升级前先确认生产环境结构

当前 PHP 安装目录为:

Plaintext
/usr/local/php

PHP-FPM 使用的 Socket 为:

Plaintext
/dev/shm/php-cgi.sock

systemd 服务文件启动的也是这个目录中的 PHP-FPM:

Plaintext
/usr/local/php/sbin/php-fpm

PHP-FPM 当前采用动态进程管理:

INI
pm = dynamic
pm.max_children = 10
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 500
request_terminate_timeout = 600s
request_slowlog_timeout = 3s

WordPress 内存设置为:

PHP
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');

升级前还确认了三个域名均指向同一个 WordPress 根目录,并且都通过同一个 PHP-FPM Socket 处理 PHP 请求。

这一步很重要,因为 PHP 升级完成后,不能只检查命令行中的 php -v,还必须确认 Nginx 实际连接的是新的 PHP-FPM。


三、调整 OneinStack 的 PHP 8.5 安装脚本

我下载了新版 OneinStack,并使用其中的 PHP 8.5 安装逻辑。

不过,直接使用原始脚本并不能完整适配当前环境,因此先进行了几项调整。

1. 调整 OPcache 配置

此次 PHP 8.5 构建完成后,php -v 已直接显示:

Plaintext
with Zend OPcache v8.5.9

因此配置中只需要保留 opcache.* 参数,不再另外把 opcache.so 当作普通外部扩展重复加载。

2. 保留 Phar

服务器中的 WP-CLI 是 Phar 文件:

Plaintext
/usr/local/bin/wp

因此 PHP 8.5 构建时必须保留 Phar,否则升级后 WP-CLI 可能无法运行。

3. 处理 iconv 头文件冲突

服务器中存在:

Plaintext
/usr/local/include/iconv.h

PHP 8.5 在配置阶段同时检测到 GNU libiconv 和系统 iconv,出现了混用冲突。

最终处理方式是在 PHP 配置、编译和安装期间临时移走该头文件,安装结束后再自动恢复。

这项处理只针对头文件,没有删除原来的 libiconv 动态库。

4. 保留必要的扩展

升级前确认当前 WordPress 实际需要的主要扩展包括:

Plaintext
mysqli
pdo_mysql
mbstring
curl
intl
zip
gd
fileinfo
Phar
LDAP
Redis
Imagick
OPcache

旧 PHP 中虽然还安装过 MongoDB 扩展,但在 WordPress 配置、Drop-in、MU Plugin 和活动插件中没有发现使用痕迹,因此本次没有重新安装 MongoDB 扩展。


四、执行 PHP 8.5.9 生产升级

正式安装时,我先停止 PHP-FPM,并将原来的 PHP 目录移动到一个带时间戳的新目录中:

Plaintext
/usr/local/php-8.1.19-before-php85-20260804-182956

随后使用 OneinStack 安装 PHP 8.5.9,并指定扩展:

Bash
cd /root/oneinstack-latest-20260804

./install.sh \
    --php_option 15 \
    --php_extensions imagick,ldap,redis

安装结束时,OneinStack 输出了:

Plaintext
####################Congratulations########################
Total OneinStack Install Time: 10 minutes

PHP install dir: /usr/local/php

但是外层安装脚本得到的状态却是:

Plaintext
INSTALL_STATUS=1
PHP 8.5.9 安装未完成。

如果只看退出状态,很容易认为整个 PHP 升级失败了。

但我没有立即重新安装,而是先检查实际结果。


五、安装状态为 1,不代表 PHP 主体没有安装成功

检查后确认:

Plaintext
PHP 8.5.9 (cli)
Zend Engine v4.5.9
Zend OPcache v8.5.9

PHP-FPM 也已经正常启动:

Plaintext
Active: active (running)

Socket 正常存在:

Plaintext
/dev/shm/php-cgi.sock

主要模块已经加载:

Plaintext
curl
fileinfo
gd
intl
ldap
mbstring
mysqli
pdo_mysql
Phar
redis
Zend OPcache
zip

三个源站请求也全部正常:

Plaintext
www.shuijingwanwq.com HTTP=200
en.shuijingwanwq.com HTTP=200
admin.shuijingwanwq.com HTTP=200

这说明 PHP 8.5.9 主体、PHP-FPM、LDAP 和 Redis 扩展实际上都已经安装成功。

继续检查安装日志后,真正导致返回状态为 1 的错误只有 Imagick:

Plaintext
fatal error: ext/standard/php_smart_string.h:
No such file or directory

PHP imagick module install failed

OneinStack 当时使用的是 Imagick 3.8.0。它在 PHP 8.5 环境中编译时引用了当前 PHP 头文件中不存在的文件,因此失败。

所以,这次不是 PHP 8.5.9 安装失败,而是附加的 Imagick 扩展安装失败。


六、改用 Imagick 3.8.1

我随后下载 Imagick 3.8.1

Plaintext
imagick-3.8.1.tgz
SHA-256:
3a3587c0a524c17d0dad9673a160b90cd776e836838474e173b549ed864352ee

第一次执行 configure 时,又遇到了新的错误:

Plaintext
Please provide a path to MagickWand-config
or Wand-config program.

系统命令中确实找不到:

Plaintext
convert
magick
MagickWand-config

但进一步检查旧 PHP 8.1 的 imagick.so 后发现,它实际链接的 ImageMagick 位于:

Plaintext
/usr/local/imagemagick

对应动态库为:

Plaintext
/usr/local/imagemagick/lib/libMagickWand-7.Q16HDRI.so.10
/usr/local/imagemagick/lib/libMagickCore-7.Q16HDRI.so.10

ImageMagick 版本为:

Plaintext
ImageMagick 7.1.1-10 Q16-HDRI

问题只是 /usr/local/imagemagick/bin 没有位于当前 PATH 中。

因此重新配置环境变量,并明确指定 ImageMagick 安装路径:

Bash
export PATH="/usr/local/imagemagick/bin:/usr/local/php/bin:$PATH"

export PKG_CONFIG_PATH="/usr/local/imagemagick/lib/pkgconfig:/usr/local/imagemagick/lib64/pkgconfig:${PKG_CONFIG_PATH:-}"

export LD_LIBRARY_PATH="/usr/local/imagemagick/lib:${LD_LIBRARY_PATH:-}"

/usr/local/php/bin/phpize

./configure \
    --with-php-config=/usr/local/php/bin/php-config \
    --with-imagick=/usr/local/imagemagick

make -j2
make install

这次编译成功,生成:

Plaintext
/usr/local/php/lib/php/extensions/no-debug-non-zts-20250925/imagick.so

随后写入 PHP 配置:

INI
[imagick]
extension=imagick.so

并重载 PHP-FPM。

最终确认:

Plaintext
imagick module version => 3.8.1
Imagick compiled with ImageMagick version =>
ImageMagick 7.1.1-10 Q16-HDRI

Imagick using ImageMagick library version =>
ImageMagick 7.1.1-10 Q16-HDRI

我还通过 PHP 实际生成了一张 2×2 像素的 PNG:

Plaintext
imagick=3.8.1 bytes=127 format=PNG

这说明 Imagick 不只是扩展能够加载,实际图像操作也可以完成。


七、验证 WordPress 是否真正运行在 PHP 8.5.9 下

升级 PHP 之后,不能只验证 PHP-FPM 进程。

我的站点还涉及:

  • WordPress;
  • Polylang;
  • W3 Total Cache;
  • Redis Object Cache;
  • 中文、英文和后台三个域名;
  • canonical 与 hreflang;
  • REST API。

因此继续进行了 WordPress 运行验证。

WP-CLI 返回:

Plaintext
WordPress:7.0.2
PHP_VERSION=8.5.9
WP_MEMORY_LIMIT=256M
WP_MAX_MEMORY_LIMIT=512M
WP_CACHE=true
ext_object_cache=true
redis=6.3.0
imagick=3.8.1
ldap=loaded
opcache=8.5.9

W3TC 的两个 Drop-in 文件也仍然存在:

Plaintext
wp-content/advanced-cache.php
wp-content/object-cache.php

Redis 服务响应正常:

Plaintext
PONG

八、验证多语言页面输出

为了避开已有页面缓存,我给请求增加了随机查询参数,并直接请求本地源站。

中文首页输出:

HTML
<html lang="zh-CN">

<link rel="alternate"
      href="https://www.shuijingwanwq.com/"
      hreflang="zh" />

<link rel="alternate"
      href="https://en.shuijingwanwq.com/"
      hreflang="en" />

<link rel="canonical"
      href="https://www.shuijingwanwq.com/" />

英文首页输出:

HTML
<html lang="en-US">

<link rel="alternate"
      href="https://www.shuijingwanwq.com/"
      hreflang="zh" />

<link rel="alternate"
      href="https://en.shuijingwanwq.com/"
      hreflang="en" />

<link rel="canonical"
      href="https://en.shuijingwanwq.com/" />

接着检查了一组互相关联的中英文文章:

Plaintext
中文文章:
https://www.shuijingwanwq.com/2026/07/31/21018/

英文文章:
https://en.shuijingwanwq.com/2026/07/31/21022/

两篇文章的:

  • <html lang>
  • canonical;
  • 中文、英文 hreflang;
  • RSS Feed;
  • oEmbed URL;
  • REST API URL;

全部指向了正确的语言域名。

这说明升级 PHP 后,Polylang 的多域名语言识别没有被破坏。


九、一次容易误判的 WP-CLI Object Cache 测试

最初我使用两个独立的 WP-CLI 进程测试 Object Cache:

第一个进程写入:

Plaintext
cache_set=true

第二个进程读取:

Plaintext
cache_get=false

直接扫描 Redis,也没有找到对应测试键。

一开始看起来像是 PHP 8.5 升级后,W3TC Redis Object Cache 已经失效。

但继续检查后发现,WP-CLI 中的对象缓存类为:

Plaintext
WP_Object_Cache

而前台 PHP-FPM 请求中的对象缓存类为:

Plaintext
W3TC\ObjectCache_WpObjectCache

也就是说,当前 WP-CLI 上下文没有加载 W3TC 的 Redis 持久化实现,只使用了 WordPress 默认的进程内对象缓存。

因此:

  • 同一个 WP-CLI 进程中可以读取刚写入的值;
  • 第二个 WP-CLI 进程无法读取;
  • 这不能用于判断前台 Redis Object Cache 是否正常。

十、通过两个独立的 FPM 请求验证 Redis Object Cache

为了验证实际前台环境,我临时创建了一个 PHP 探针,通过两个独立 HTTP 请求分别执行:

PHP
wp_cache_set()
wp_cache_get()
wp_cache_delete()

在中文域名下写入后,第二个中文请求能够读取:

Plaintext
host=www.shuijingwanwq.com
object_cache_class=W3TC\ObjectCache_WpObjectCache
set=true

found=true
value=www.shuijingwanwq.com

在英文域名下写入后,第二个英文请求也可以读取:

Plaintext
host=en.shuijingwanwq.com
object_cache_class=W3TC\ObjectCache_WpObjectCache
set=true

found=true
value=en.shuijingwanwq.com

这证明 W3TC Redis Object Cache 在 PHP 8.5.9 的 FPM 环境中可以跨请求持久化。

更重要的是,中文域名写入的对象,在英文域名中读取不到:

Plaintext
www 写入
en 读取:
found=false

英文域名写入的对象,在中文域名中同样读取不到:

Plaintext
en 写入
www 读取:
found=false

最终两边都能精确删除测试对象:

Plaintext
delete=true

这次验证确认了两件事:

  1. PHP 8.5.9 下的 W3TC Redis Object Cache 正常;
  2. 中文站和英文站的 Object Cache 已经按 Host 隔离。

测试结束后,临时 PHP 探针也已经自动删除。

整个过程没有清空 Redis,也没有执行 W3TC 的 Purge All Caches。


十一、REST API 与错误日志验证

中文站和英文站的 REST API 均返回 200

Plaintext
www.shuijingwanwq.com REST HTTP=200
en.shuijingwanwq.com REST HTTP=200

随后检查 PHP-FPM 和 Nginx 错误日志,没有发现:

Plaintext
Fatal error
Parse error
Uncaught exception
Segmentation fault
Cannot load
Undefined symbol
upstream prematurely closed
connect failed

最终三个源站仍然正常:

Plaintext
www.shuijingwanwq.com HTTP=200
en.shuijingwanwq.com HTTP=200
admin.shuijingwanwq.com HTTP=200

十二、PHP 8.5 暴露出的插件 Deprecated 提示

PHP 8.5 升级完成后,WP-CLI 输出中出现了几类兼容性提示。

1. SyntaxHighlighter Evolved

当前版本为:

Plaintext
SyntaxHighlighter Evolved 3.7.2

插件源码中存在:

PHP
case 'false';
default;

PHP 8.5 提示应使用冒号:

PHP
case 'false':
default:

不过,我当前正在批量处理历史 SyntaxHighlighter 文章。等历史文章全部转换完成后,这个插件会直接停用。

因此这次没有修改第三方插件源码。

2. Organize Series

Organize Series 使用了:

PHP
SplObjectStorage::attach()
SplObjectStorage::contains()

PHP 8.5 已经为这两个方法输出 Deprecated,建议改用:

PHP
SplObjectStorage::offsetSet()
SplObjectStorage::offsetExists()

目前这些提示没有导致前台错误,因此没有和 PHP 升级同时处理,后续再单独检查。

3. WP-CLI 的 Deprecated 输出

执行一条包含无效字段的 WP-CLI 命令时,曾连续出现:

Plaintext
Using null as an array offset is deprecated

但重新使用正常命令,并分别捕获标准输出和标准错误后,结果为:

Plaintext
command_status=0
stderr_bytes=0
json_valid=true

说明当前 WP-CLI 2.12.0 在 PHP 8.5.9 下仍可正常输出和解析 JSON,不影响正在运行的历史文章批处理。


十三、删除 OneinStack 自动留下的 xprober.php

OneinStack 安装结束后,在默认站点目录中留下了:

Plaintext
/data/wwwroot/default/xprober.php

这个文件可以输出大量服务器和 PHP 环境信息,没有必要长期暴露在 Web 目录中。

我先将它备份到:

Plaintext
/root/xprober.php.after-php85-20260804-190732

随后从公开目录中删除,并限定检查了:

Plaintext
/data/wwwroot/default
/data/wwwroot/www.shuijingwanwq.com

最终没有发现其他公开的 xprober.php 副本。

删除后 PHP-FPM 和三个域名仍然正常。


十四、最终升级结果

这次 PHP 升级最终完成情况如下:

Plaintext
PHP 8.1.19 → PHP 8.5.9:通过
PHP-FPM:通过
Zend OPcache 8.5.9:通过
Redis PHP 扩展 6.3.0:通过
Imagick 3.8.1:通过
ImageMagick 7.1.1-10:通过
LDAP:通过
Phar / WP-CLI:通过
WordPress 7.0.2:通过
W3TC Redis Object Cache:通过
www / en Object Cache Host 隔离:通过
中文页面 lang / canonical / hreflang:通过
英文页面 lang / canonical / hreflang:通过
REST API:通过
www / en / admin 三个源站:通过

需要区分的是:

Plaintext
Redis PHP 扩展:已经随 PHP 8.5 重新编译
Redis 服务端:仍然是 7.0.11
Nginx:仍然是 1.24.0

所以这次完成的是 PHP 层升级,不是整个服务器软件栈的统一升级。


十五、后续计划

目前服务器正在批量处理历史 WordPress 文章。

在这个阶段继续升级 Nginx 或 Redis 服务端,会让生产环境同时叠加太多变量。一旦出现批处理超时、对象缓存异常或页面输出变化,很难快速区分是文章处理脚本的问题,还是底层服务升级造成的。

因此接下来的安排是:

  1. 继续完成历史文章转换;
  2. 文章处理完成后停用 SyntaxHighlighter;
  3. 单独处理仍有必要保留的 PHP 8.5 Deprecated;
  4. 下一轮只升级 Nginx;
  5. Nginx 稳定后,再单独升级 Redis 服务端。

这次升级过程中最值得记录的一点是:

安装脚本返回非零状态,并不一定代表整个软件已经无法使用。

正确的处理方式不是看到 INSTALL_STATUS=1 就立即重装,而是继续确认:

  • 哪个组件失败;
  • PHP 主体是否已安装;
  • PHP-FPM 是否运行;
  • Socket 是否存在;
  • 必要扩展是否加载;
  • WordPress 是否正常启动;
  • 多域名语言输出是否正确;
  • Object Cache 是否真正跨请求持久化;
  • 服务日志中是否存在致命错误。

最终确认,这次状态为 1 的原因只是 Imagick 3.8.0 编译失败。补装 Imagick 3.8.1 后,PHP 8.5.9 已经在当前 WordPress 多域名生产环境中稳定运行。

从 CPU 再次告警到 ECS 升配:WordPress 服务器从 1 核 2G 升级到 2 核 4G 实录

WordPress 网站维护、性能优化与博客运营咨询

本站已持续运营超过 10 年,累计发布 1000+ 篇原创技术文章,长期实践 WordPress 网站建设、CDN / Cloudflare 配置、缓存优化、Google SEO、广告变现和多语言网站运营。

如果你的 WordPress 网站遇到访问慢、缓存异常、插件冲突、广告不显示、SEO 基础结构混乱、CDN 配置不确定等问题,可以联系我做一次远程技术排查。

适合以下用户:
✅ 个人博客站长
✅ WordPress 网站运营者
✅ 独立开发者与内容创作者
✅ SaaS 产品官网运营团队
✅ 希望优化网站速度与稳定性的站点

服务内容:
✅ WordPress 速度优化
✅ Cloudflare / CDN / 缓存配置排查
✅ 插件冲突与页面异常排查
✅ AdSense 广告显示问题排查
✅ SEO 基础结构检查
✅ 博客运营与商业化咨询

如需了解方案或交流相关问题,请直接联系我,并注明:WordPress 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理