项目交付报告:Amazon Linux 2023 环境下 PHP 5.6 并行部署实施方案
文档版本:1.0
实施环境:Amazon Linux 2023 (AL2023)
目标组件:PHP 5.6.40 (配合 Nginx)
核心策略:源码编译 + 依赖沙盒化 + 运行时环境隔离
1. 核心挑战与技术背景 (Challenges)
在 AL2023 上部署 PHP 5.6 并非简单的软件安装,而是一次跨越 10 年技术代差的系统集成。主要面临以下四大核心技术冲突:
OpenSSL 版本断层 (Critical)
- 冲突点:AL2023 内置 OpenSSL 3.0,API 已完全重构;PHP 5.6 仅支持 OpenSSL 1.0.x。
- 后果:直接编译会报
libssl相关符号未定义,无法建立 HTTPS 连接。
Glibc 头文件变更
- 冲突点:AL2023 的 Glibc (2.34+) 彻底移除了
xlocale.h;PHP 依赖的旧版 ICU 库硬编码了该头文件。 - 后果:编译 ICU 时中断,提示
fatal error: xlocale.h: No such file or directory。
- 冲突点:AL2023 的 Glibc (2.34+) 彻底移除了
编译器标准不兼容
- 冲突点:系统默认 GCC 11 使用 C++17 标准;旧版 ICU 代码不符合新语法规范。
- 后果:编译过程中出现大量 C++ 语法警告和错误。
链接库冲突
- 冲突点:PHP 5.6 需要 GNU 版本的
libiconv,而现代 Linux 将其整合在 glibc 中,链接器无法自动识别。 - 后果:
make阶段报错undefined reference to libiconv_open。
- 冲突点:PHP 5.6 需要 GNU 版本的
2. 详细执行过程 (Execution Steps)
为了解决上述冲突,我们采用了 “沙盒化依赖构建” 策略:将所有旧版依赖库安装到 /usr/local 下的独立目录,不污染系统原有环境。
第一阶段:基础环境准备
安装编译工具,并建立目录软链接以适配 AL2023 的文件结构。
# 1. 安装开发工具包
dnf groupinstall "Development Tools" -y
dnf install -y libxml2-devel sqlite-devel libcurl-devel \
libpng-devel libjpeg-devel freetype-devel bzip2-devel \
libxslt-devel systemd-devel libzip-devel gettext-devel gcc-c++
# 2. 创建 www 用户
id -u www &>/dev/null || useradd -s /sbin/nologin -M www
# 3. 修复 Freetype 路径 (AL2023 路径变更适配)
mkdir -p /usr/local/include
ln -sf /usr/include/freetype2 /usr/local/include/freetype第二阶段:编译“古董”依赖库 (沙盒化)
策略:手动编译 OpenSSL 1.0.2、ICU 58、Libiconv,并锁定安装路径。
1. OpenSSL 1.0.2u (解决 SSL 冲突)
cd /usr/local/src
wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2u.tar.gz
tar -zxvf openssl-1.0.2u.tar.gz && cd openssl-1.0.2u
./config --prefix=/usr/local/ssl-1.0.2 --openssldir=/usr/local/ssl-1.0.2 shared zlib
make -j$(nproc) && make install2. Libmcrypt (系统缺失补充)
cd /usr/local/src
wget https://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz
tar -zxvf libmcrypt-2.5.8.tar.gz && cd libmcrypt-2.5.8
./configure --prefix=/usr/local
make -j$(nproc) && make install3. ICU4C 58.3 (解决 Intl 扩展问题)
关键操作:使用 sed 修复头文件引用,指定 C++11 标准。
cd /usr/local/src
wget https://github.com/unicode-org/icu/releases/download/release-58-3/icu4c-58_3-src.tgz
tar -zxvf icu4c-58_3-src.tgz && cd icu/source
# 修复 xlocale.h 错误 (适应新版 Glibc)
sed -i 's/xlocale.h/locale.h/g' i18n/digitlst.cpp
# 指定 C++11 标准 (适应 GCC 11)
./configure --prefix=/usr/local/icu-58 CXXFLAGS="-std=c++11"
make -j$(nproc) && make install4. GNU Libiconv 1.15 (解决链接错误)
cd /usr/local/src
wget https://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.15.tar.gz
tar -zxvf libiconv-1.15.tar.gz && cd libiconv-1.15
./configure --prefix=/usr/local/libiconv
make -j$(nproc) && make install第三阶段:PHP 5.6 编译与修复
策略:通过环境变量注入依赖路径,并手动修改 Makefile 解决链接器错误。
1. 配置 (Configure)
cd /root/php-5.6.9 # 假设源码在此
make clean # 清理旧配置
# 注入依赖库路径
export PKG_CONFIG_PATH=/usr/local/ssl-1.0.2/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/usr/local/ssl-1.0.2/lib:/usr/local/icu-58/lib:$LD_LIBRARY_PATH
./configure --prefix=/usr/local/php56 \
--with-config-file-path=/usr/local/php56/etc \
--enable-fpm --with-fpm-user=www --with-fpm-group=www \
--with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \
--with-iconv-dir --with-freetype-dir=/usr/local --with-jpeg-dir --with-png-dir \
--with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath \
--enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization \
--with-curl=/usr --enable-mbregex --enable-mbstring \
--with-mcrypt=/usr/local --with-gd --enable-gd-native-ttf \
--with-openssl=/usr/local/ssl-1.0.2 --with-mhash \
--enable-pcntl --enable-sockets --enable-zip --enable-soap \
--enable-intl --with-icu-dir=/usr/local/icu-582. 修复 Makefile (关键 Hack)
原因:Configure 脚本无法自动识别手动安装的 libiconv 和 C++ 库依赖。
操作:编辑 Makefile,修改 EXTRA_LIBS 行。
# 修改前示例:EXTRA_LIBS = -lcrypt ...
# 修改后逻辑:在开头加 -L路径,在结尾加 -l库名
EXTRA_LIBS = -L/usr/local/libiconv/lib -L/usr/local/ssl-1.0.2/lib -L/usr/local/icu-58/lib ... (原有内容) ... -lstdc++ -liconv3. 编译与安装
操作:使用空文件欺骗法绕过 phar 构建错误。
make -j$(nproc)
# 绕过 phar 错误 (因环境问题导致 CLI 无法在安装阶段运行)
touch ext/phar/phar.phar
# 必须带环境变量执行安装
export LD_LIBRARY_PATH=/usr/local/ssl-1.0.2/lib:/usr/local/libiconv/lib:/usr/local/icu-58/lib:$LD_LIBRARY_PATH
make install第四阶段:配置与服务化
策略:端口隔离,并通过 Systemd 注入运行时环境变量。
1. 配置文件初始化
cp /root/php-5.6.9/php.ini-production /usr/local/php56/etc/php.ini
cp /usr/local/php56/etc/php-fpm.conf.default /usr/local/php56/etc/php-fpm.conf
# 修改端口为 9056 (防止与系统 PHP 9000 端口冲突)
sed -i 's/listen = 127.0.0.1:9000/listen = 127.0.0.1:9056/g' /usr/local/php56/etc/php-fpm.conf2. 创建 Systemd 服务
文件:/etc/systemd/system/php56-fpm.service
核心逻辑:通过 Environment 指令,让 PHP 进程启动时能加载到我们在 /usr/local 下编译的旧版库。
[Service]
# ...
ExecStart=/usr/local/php56/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php56/etc/php-fpm.conf
# 关键:加载沙盒库
Environment="LD_LIBRARY_PATH=/usr/local/ssl-1.0.2/lib:/usr/local/libiconv/lib:/usr/local/icu-58/lib"3. 启动
systemctl daemon-reload
systemctl start php56-fpm
systemctl enable php56-fpm3. 验证与交付 (Verification)
1. 端口验证
检查 9056 端口是否由 PHP-FPM 监听:
netstat -tulpn | grep 9056
# 预期输出: tcp ... 127.0.0.1:9056 ... php-fpm2. 功能验证 (Nginx 路由)
配置 Nginx 特定路由指向新端口:
location = /textll.php {
fastcgi_pass 127.0.0.1:9056;
include fastcgi.conf;
}访问测试页面,phpinfo() 应显示版本为 5.6.9。
3. 系统影响评估
- 安全性:系统自带 OpenSSL 3.0 未被替换,系统安全性不受影响。
- 稳定性:PHP 5.6 运行在独立目录和端口,与系统原有 PHP 5.4 互不干扰。
- 可维护性:所有自定义依赖均在
/usr/local下有清晰目录,卸载只需删除对应文件夹。
4. 结论 (Conclusion)
通过上述方案,我们成功攻克了 OpenSSL 版本不兼容、基础库缺失、编译器标准冲突等一系列难题。该方案在保证 Amazon Linux 2023 系统纯净性的前提下,完美实现了 PHP 5.6 的并行运行,满足了旧业务系统的迁移需求。
公众号:运维躬行录
个人博客:躬行笔记