PHP 8.0 升级到 8.3 需分步实施(8.0→8.1→8.2→8.3),逐级应对枚举、只读类、动态属性废弃等破坏性变更,配合PHPCompatibility、Rector、PHPStan自动化扫描修复,并重置vendor、更新Web服务器配置及php.ini。

PHP 8.0 升级到 8.3 不是简单换版本,而是要应对一系列破坏性变更、扩展兼容性调整和框架适配。老项目尤其需要分步验证,跳过中间版本容易漏掉关键警告(比如 PHP 8.1 的枚举语法、8.2 的只读类、8.3 的显式类型声明强化)。下面按实操逻辑梳理关键步骤。
确认当前环境与目标兼容性
先别急着装新版本,得摸清底子:
- 运行
php -v和php --modules,记下实际启用的扩展(特别是mysql——它在 8.0 已被移除,但有些老代码还在用) - 检查
composer.json中"php"字段是否允许^8.3;若写死"^8.0",需手动放宽 - 运行
composer check-platform-reqs,看是否有扩展缺失或版本不匹配(如ext-gd、ext-opcache) - 查框架支持:Laravel 9 支持 PHP 8.0–8.2,Laravel 10 起才正式支持 8.3;ThinkPHP 8.0 要求最低 PHP 8.1
逐级升级更稳妥(推荐路径:8.0 → 8.1 → 8.2 → 8.3)
直接从 8.0 跳 8.3 容易踩坑,因为每版都有渐进式收紧:
-
8.0 → 8.1:重点处理
enum关键字冲突(避免类名/常量叫enum)、never类型、array_is_list()等新函数替代逻辑 -
8.1 → 8.2:关注只读类(
readonly class)、new Foo()构造器参数提升、mysqli_fetch_all()返回类型变更 -
8.2 → 8.3:严格校验动态属性(
#[\AllowDynamicProperties]需显式加)、str_starts_with()等函数不再容忍null参数、mbstring默认编码改为 UTF-8
每次升级后,务必开启完整错误报告:error_reporting = E_ALL | E_DEPRECATED,并检查日志中是否出现 Deprecated 或 Warning ——它们在 8.3 中很可能变成 Fatal Error。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
立即学习“PHP免费学习笔记(深入)”;
自动化检测与代码修复
靠人工扫代码效率低还易漏,用工具提前拦截:
-
PHPCompatibility:静态扫描兼容性问题,命令示例:
phpcbf --standard=PHPCompatibility --runtime-set testVersion 8.3 . -
Rector:自动改写废弃语法,比如把
create_function()替换为匿名函数,把each()换成foreach -
PHPStan:配合
phpstan-php83扩展,提前发现类型不匹配(如数组访问未判空、返回值类型缺失) - 特别注意字符串比较:
==在 8.3 中对数字字符串更严格,建议统一改用===或strcmp()
运行环境与依赖重置
升级 PHP 版本后,不能复用旧 vendor/ 和配置:
- 删掉
vendor/和composer.lock,再执行composer install——否则可能加载到仅兼容 8.0 的旧包 - 检查 Web 服务器配置:Nginx 的
fastcgi_pass必须指向 PHP 8.3 的 socket(如unix:/run/php/php8.3-fpm.sock);Apache 要禁用php8.0模块,启用php8.3 - 更新
php.ini:8.3 默认禁用assert.exception = 0,若项目依赖assert()抛异常,需显式设为1 - 数据库连接层:确保用的是
PDO或mysqli,彻底清理mysql_*调用(8.0 已移除,8.3 连存根都没有)


















