php版本迁移需重点排查扩展兼容性、语法弃用及运行时行为变化,如mysqli连接方式、json_decode返回类型、opcache预加载失败等,并验证composer依赖与真实请求路径。

PHP 版本迁移不是简单换 php 命令就能完事的,核心风险在扩展兼容性、语法弃用和运行时行为变化——尤其从 PHP 7.4 升到 8.0+ 或跨大版本(如 5.6 → 7.4)时,mysqli 默认连接方式、json_decode 返回类型、错误处理模型都可能直接导致服务崩溃。
确认当前环境与目标版本的扩展差异
PHP 大版本升级常伴随扩展移除或重命名。比如 PHP 8.0 移除了 mysql 扩展(非 mysqli),PHP 8.2 废弃了 create_function();而 ext/zip 在 8.0+ 要求 libzip ≥ 1.8.0,否则 ZipArchive::setPassword() 会静默失败。
- 运行
php -m和php --ini记下已启用模块与配置路径 - 对比目标版本的 PHP 8.0 不兼容变更 或对应版本的 migration 文档
- 用
php -v和php -r "print_r(get_extension_funcs('openssl'));"快速验证关键扩展函数是否可用
检查代码中被废弃或行为变更的语法与函数
静态扫描只能发现一部分问题,但能快速暴露高危点。例如 each() 在 PHP 7.2+ 已移除,array_key_exists(null, $arr) 在 PHP 8.0+ 返回 false(之前是 true),mbstring.func_overload 在 7.4+ 被彻底删除。
- 用
phpstan或phpcs配合SlevomatCodingStandard.PHP.DeprecatedFunctions规则扫描 - 重点 grep:
grep -r "create_function\|each\|mysql_\|call_user_method\|zend_version" ./src/ - 对
json_decode($str, true)检查是否依赖null值被转为空数组(PHP 8.0+ 不再自动转换)
容器或系统级迁移时的配置陷阱
很多问题不出现在代码里,而出现在 php.ini 或 SAPI 配置中。比如 PHP 8.0+ 默认开启 opcache.preload,若 preload 文件里引用了未声明的类,整个 PHP-FPM 进程启动失败,错误日志只显示 "Failed to preload",无具体路径。
立即学习“PHP免费学习笔记(深入)”;
- 对比新旧
php.ini:关注short_open_tag(8.0+ 默认 off)、precision(影响浮点数 JSON 输出)、error_reporting(8.0+ 默认含E_DEPRECATED) - FPM 场景下检查
www.conf中php_admin_value[extension]是否硬编码了已移除扩展 - Docker 用户注意基础镜像标签:
php:8.0-cli和php:8.0-cli-bullseye的默认扩展列表不同,后者不含gd(需手动apt install libpng-dev+docker-php-ext-install gd)
最常被跳过的一步是验证 Composer 依赖与 PHP 版本约束。即使代码全兼容,composer install 也可能因 composer.json 中 "php": "^7.4" 锁死解析器,或第三方包的 require 写死 "ext-mcrypt": "*"(PHP 7.2+ 已移除)。别只测 hello world —— 把真实请求路径(尤其是带上传、JSON API、定时任务)全跑一遍,观察日志里有没有 Deprecated: 或 Uncaught TypeError。











