本文目录导读:

PHP项目版本升级是一个需要谨慎对待的过程,稍有不慎就可能导致线上故障,为了确保升级平稳,建议从环境准备、代码兼容性、依赖管理、数据库、测试及回滚六个维度进行把控。
以下是详细的注意事项清单:
环境与依赖检查(底层基石)
- 确认运行环境:明确当前服务器操作系统(如 CentOS 7 已停止维护,需考虑系统升级)和 Web 服务器(Nginx/Apache)对目标 PHP 版本(如 8.2、8.3)的支持情况。
- 查看官方迁移指南:务必阅读 PHP 官方发布的 UPGRADING 文档(如从 7.4 升级到 8.0,或 8.1 到 8.2),列出所有废弃(Deprecated)和移除(Removed)的函数。
- 扩展(Extension)兼容性:这是最常踩坑的地方。
- 检查
php -m列出的扩展,确认是否在目标版本中存在。 - 重点关注
php-mysql(旧版)与php-mysqli/pdo_mysql的切换。 - 检查
php-gd、php-mbstring、php-intl、php-redis、php-mongodb等扩展的版本更新。
- 检查
代码兼容性与语法重构(核心工作)
- 废弃/移除函数替换:
each()、create_function()、money_format()等已被移除,需用现代替代方案。- 注意 *`mysql_`** 系列函数(PHP 7 已移除),确认项目是否还残留旧代码。
- 特性变更:
implode()参数顺序要求更严格,必须保证分隔符和数组顺序正确。- *`array_`** 系列函数对类型的要求更严格(更倾向于强类型)。
str_replace()、substr()等函数在处理null值时的行为变化(在 PHP 8.1 后,传递null会触发 Deprecated 警告)。
- 类型系统(PHP 8 特有):
- 引入了联合类型、匹配表达式(match) 等新特性,虽然不影响旧代码,但需注意弱类型比较的底层逻辑变化(如字符串与数字比较规则改变,可能导致
0 == "foo"的结果变化)。
- 引入了联合类型、匹配表达式(match) 等新特性,虽然不影响旧代码,但需注意弱类型比较的底层逻辑变化(如字符串与数字比较规则改变,可能导致
- 错误处理机制:
- PHP 8 将许多 E_NOTICE 提升为 E_WARNING 或 TypeError,如果项目未开启严格的错误屏蔽,需要处理这些新出现的警告,尤其是“Undefined array key”这类提示,建议代码中显式进行
isset()或 判断。
- PHP 8 将许多 E_NOTICE 提升为 E_WARNING 或 TypeError,如果项目未开启严格的错误屏蔽,需要处理这些新出现的警告,尤其是“Undefined array key”这类提示,建议代码中显式进行
数据库交互(高风险区)
- 字符集问题:确保数据库连接使用
utf8mb4,避免因版本升级导致中文乱码。 - SQL 模式:PHP 升级后,配合 MySQL 8+ 时,注意严格模式(STRICT_TRANS_TABLES)的影响,可能暴露之前隐藏的 SQL 错误。
- 预处理语句:检查 PDO 或 mysqli 用法,确保没有使用不安全的转义函数(如
addslashes),新版本对类型校验更严格,预处理更适合。
第三方依赖(Composer)
- 锁定文件:升级前,备份
composer.lock。 - 依赖要求:检查
composer.json中的require,确认包是否支持目标 PHP 版本,老旧包(如老版 Laravel、Symfony、ThinkPHP)可能无法运行在 PHP 8.2+ 上,执行composer update前,先运行composer check-platform-reqs。 - 移除废弃包:移除不再兼容的 PHPUnit 或 PhpSpreadsheet 等版本。
测试策略(安全保障)
- 自动化测试:在升级后的环境中跑一遍完整的单元测试(PHPUnit/Pest),重点检查 “Undefined array key” 和 “xx(): Argument #1 must be of type” 这类异常。
- 回归测试:重点测试登录、支付、文件上传、Excel 导出等涉及底层函数的功能。
- 灰度发布:不要直接在生产环境替换,先在 staging 环境(预发布)跑 2-3 天,观察 Error Log 和 CPU 内存占用。
上线与回滚方案
- 全量备份:备份代码(Git Tag)和数据库(mysqldump)。
- 平滑切换:对于高可用环境,建议先升级部分节点(如负载均衡中的一台),观察流量正常后再全量切换。
- 快速回滚:由于 PHP 是解释型语言,回滚通常很简单(切换软链接
php-v7或php-v8即可),但要确保数据库结构没有因升级而改变,否则回滚后数据可能不兼容。
额外特别提醒(针对 PHP 8.0+)
- JIT(即时编译):如果你使用了 JIT,需重新配置
opcache参数,配置文件需要调整。 - 属性构造器(Constructor Property Promotion):如果使用了该新特性,注意旧代码中的
setX方法命名冲突问题。 str_contains():新函数很好用,但要注意不要在代码中重复定义同名函数,建议使用命名空间或检查function_exists()。
总结操作顺序建议
- 本地/容器环境:使用 Docker 快速拉取目标 PHP 版本镜像,运行项目。
- 静态扫描:使用 PHPStan 或 Psalm 检测代码,处理潜在的类型和废弃函数问题。
- Composer 更新:更新依赖。
- 全面测试:跑通测试套件。
- 部署预发布:观察日志。
- 正式切换:切换版本并开启
display_errors(仅线上关闭)对比日志。
如果在升级中遇到具体的报错,欢迎提供具体的 PHP 版本号(如 7.4 升 8.2)和报错信息,我可以帮你进一步分析解决方案。