Docker是复刻旧版PHP运行上下文的可靠方案,须指定带发行版后缀的精确镜像(如php:7.2.34-apache-buster),严格还原扩展(含mcrypt-1.0.4)、启用short_open_tag、显式设置date.timezone为Asia/Shanghai。

旧版PHP应用(比如PHP 5.6、7.0或7.2)在现代系统上直接运行常遇到扩展缺失、函数废弃、SSL/TLS握手失败、时区报错等问题。Docker不是“让老代码跑起来”的临时补丁,而是用隔离环境精准复刻当年的运行上下文——关键不在“能跑”,而在“像当年一样稳定地跑”。
锁定原始PHP版本与扩展组合
别用php:7.2-apache这种模糊标签,必须指定带发行版后缀的镜像,例如:
php:7.2.34-apache-buster(Debian 10)或php:5.6.40-apache-stretch(Debian 9)。这些镜像保留了对应年代的glibc、OpenSSL 1.1.0/1.0.2、curl版本和默认编译参数。
扩展安装严格按原始方式还原:
- mysqli、pdo、openssl等核心扩展用
docker-php-ext-install,不走apt包管理 - mcrypt已废弃?那就用
pecl install mcrypt-1.0.4并手动启用,而非跳过 - 如果原应用依赖
mysql_connect()(非PDO),需额外启用extension=php_mysql.dll(Windows)或编译legacy mysql扩展(Linux)
复刻关键运行时配置
旧版PHP对php.ini敏感度极高,不能只改几个参数就完事:
立即学习“PHP免费学习笔记(深入)”;
-
date.timezone必须显式设为Asia/Shanghai或PRC(注意:Alpine中PRC不可靠,优先用Asia/Shanghai) -
short_open_tag = On——很多老项目用而非<?php -
register_globals = Off要确认是否真关掉;有些老CMS反而依赖它开启(极少见,但存在) -
mbstring.func_overload = 2若原环境启用了,容器里也得配,否则中文处理异常
所有配置建议拆进/usr/local/etc/php/conf.d/下的独立文件,避免覆盖主ini导致升级混乱。
兼容性细节兜底处理
光有PHP还不够,Web服务器、SSL、文件权限等环节都可能卡住:
- Apache 2.4+默认禁用
.htaccess,老项目重写规则会失效 → 在apache2.conf或虚拟主机配置中加AllowOverride All - 若应用调用
file_get_contents('https://...')报SSL错误,说明OpenSSL版本不匹配 → 换用php:7.2-apache-stretch(自带OpenSSL 1.0.2)而非-buster(OpenSSL 1.1.1) - 挂载本地代码时,macOS/Windows用户常遇权限问题 → 启动容器加
--user www-data,或提前chown -R 33:33 ./src(www-data UID/GID为33) - Session路径若硬编码为
/tmp,而容器中/tmp被tmpfs挂载且无写权限 → 改用session.save_path = "/var/www/sessions"并RUN mkdir -p /var/www/sessions && chown www-data:www-data /var/www/sessions
验证是否真正“完美运行”
不能只看首页能打开,要逐层验证:
- 执行
php --ini确认加载的配置路径和文件顺序 - 运行
php -m | grep -E 'mysql|mcrypt|gd'检查扩展是否真实加载(不只是出现在ini里) - 访问
phpinfo()页面,核对Loaded Configuration File、Scan this dir for additional .ini files、Registered PHP Streams三项 - 模拟真实请求:
curl -I http://localhost/login.php看状态码和Header是否符合预期(比如是否返回Set-Cookie、X-Powered-By是否一致) - 触发一个含数据库写入、文件上传、中文输出的完整业务流程,观察日志有无警告(
Notice级错误在旧版中常被忽略,但新环境可能报错)



















