标题提到的PHP 8.2,在本文写作时(2022年9月)尚未正式发布,正式版于2022年12月发布。我是在RC版本出来后,第一时间尝试的。

从兴奋尝试,到踩坑无数,再到差点放弃,最后找到平衡点。本文分享我这段时间的经历,包括PHP 8.2的新特性、踩过的坑、性能变化,以及最终的选择。

一、为什么尝试PHP 8.2

1. 对新特性的期待

PHP 8.2的新特性,让我很期待:

  • 只读类(Readonly Classes):终于可以更方便地定义不可变对象
  • 动态属性弃用:让代码更规范
  • 新的类型系统:true、false、null作为独立类型
  • 性能优化:每次大版本都有性能提升
  • 新的函数和类:让开发更高效

作为一个PHP老用户,每次新版本发布,我都会第一时间尝试。

2. 项目背景

我有一个个人项目,用的是PHP 8.1。项目不大,代码量不多,适合用来尝试新版本。

我想:"反正项目不大,出了问题也容易回滚。先在这个项目上试试PHP 8.2,没问题了再推广到其他项目。"

于是,我把这个项目升级到了PHP 8.2 RC版本。

二、入门:新特性体验

刚开始,我对PHP 8.2的新特性充满了热情。

1. 只读类

只读类是PHP 8.2最让我期待的特性。

在PHP 8.1中,只有只读属性,每个属性都要加readonly关键字:

class User {
    public readonly string $name;
    public readonly int $age;
    
    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
}

PHP 8.2中,可以直接在类上加readonly,所有属性都是只读的:

readonly class User {
    public string $name;
    public int $age;
    
    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
}

这个特性,对于值对象(Value Object)来说太方便了。我把项目中所有的值对象都改成了只读类,代码简洁了很多。

2. 新类型系统

PHP 8.2允许true、false、null作为独立的类型:

function alwaysTrue(): true {
    return true;
}

function alwaysFalse(): false {
    return false;
}

还有交集类型的改进,以及DNF类型(Disjunctive Normal Form)。

这些新类型,让类型声明更精确了。我尝试在项目中使用,但发现实际用到的场景不多。

3. 新函数

PHP 8.2新增了一些函数:

  • mysqliexecutequery:简化mysqli查询
  • arraykeyfirstarraykeylast的改进
  • 一些字符串和数组函数的改进

这些新函数,有些挺实用的,有些感觉用处不大。

4. 弃用的功能

PHP 8.2弃用了一些功能:

  • 动态属性:给未声明的属性赋值,会抛出Deprecated警告
  • 某些utf8encodeutf8decode的用法
  • ${}字符串插值语法

弃用动态属性,我觉得是好事,能让代码更规范。但也给我带来了麻烦(后面细说)。

三、踩坑:从入门到差点放弃

好景不长,尝试了几天后,我开始踩坑了。

坑一:动态属性的坑

这是最大的坑。

PHP 8.2弃用了动态属性。我的项目中,有一些代码用了动态属性:

class Config {
    // 没有声明属性
}

$config = new Config();
$config->database = 'mysql'; // 动态属性,PHP 8.2中弃用

这些代码,在PHP 8.1中没问题,但在PHP 8.2中会抛出Deprecated警告。

更麻烦的是,我依赖的一些第三方包,也用了动态属性。这些包还没有适配PHP 8.2,升级后满屏都是警告。

我花了两天时间,把自己代码中的动态属性都改了:

  • 能声明属性的,都声明了
  • 必须用动态属性的,加了#[AllowDynamicProperties]注解
  • 第三方包的问题,要么升级,要么临时屏蔽警告

改完之后,警告少了很多,但还是有一些第三方包的问题没解决。

坑二:只读类的限制

只读类用起来很爽,但限制也很多:

  • 只读类不能被继承(除非子类也是只读的)
  • 只读类的属性不能有默认值
  • 只读类不能有静态属性
  • 只读类不能用__set魔术方法

我有一个类,本来想改成只读类,但因为需要被继承,改不了。还有一个类,因为属性需要默认值,也改不了。

最后,只有一部分值对象改成了只读类,其他的还是用老写法。

坑三:第三方包不兼容

这是最头疼的问题。

我项目中用了十几个第三方包,其中有三四个不兼容PHP 8.2:

  • 有的包用了动态属性,满屏警告
  • 有的包用了被弃用的函数
  • 有的包类型声明有问题,在PHP 8.2中报错
  • 有的包已经停止维护了,不会适配PHP 8.2

为了这些包,我花了很多时间:

  • 能升级的,升级到最新版本
  • 不能升级的,找替代包
  • 找不到替代的,临时打补丁
  • 实在不行的,只能屏蔽错误

折腾了好几天,才把第三方包的问题基本解决。

坑四:性能没有明显提升

升级前,我期待PHP 8.2有性能提升。

但实际测试后,发现性能提升不明显:

  • 接口响应时间:和PHP 8.1差不多
  • 内存使用:略有下降,但不明显
  • 编译速度:差不多

可能是因为我的项目太小,性能差异不明显。也可能是RC版本的优化还没到位。

总之,性能没有给我惊喜。

坑五:开发工具不兼容

升级PHP 8.2后,一些开发工具也出了问题:

  • IDE的PHP插件,还不支持PHP 8.2的新语法
  • 静态分析工具(PHPStan),需要升级到最新版本才支持
  • 代码格式化工具(PHP-CS-Fixer),也需要升级
  • Debug工具,偶尔会出问题

这些工具的问题,虽然不影响运行,但影响开发体验。

四、挣扎:要不要放弃

踩了这么多坑,我开始犹豫:要不要放弃PHP 8.2,回退到8.1?

1. 放弃的理由

  • 第三方包不兼容,维护成本高
  • 性能提升不明显
  • 新特性用到的不多
  • 开发工具不兼容,影响效率
  • RC版本可能还有bug,不稳定

2. 坚持的理由

  • 只读类确实好用,代码更简洁
  • 动态属性弃用,能倒逼代码质量提升
  • 提前适配,正式版发布后就能顺利升级
  • 学习新特性,提升自己
  • PHP 8.2是未来的方向,迟早要升级

3. 最终选择

纠结了很久,我最终选择了折中:

  • 个人项目继续用PHP 8.2,跟进新版本
  • 生产项目暂时用PHP 8.1,等PHP 8.2正式版发布、第三方包都适配后再升级
  • 在个人项目中积累经验,为以后的升级做准备

这样,既不会影响生产环境的稳定,又能跟进新版本。

五、PHP 8.2新特性总结

经过这段时间的使用,我对PHP 8.2的新特性有了更客观的认识。

1. 值得用的新特性

  • 只读类:对于值对象非常实用,推荐使用
  • 动态属性弃用:虽然带来了迁移成本,但长期来看是好事
  • 新类型系统:在特定场景下有用,能让类型更精确
  • 性能优化:虽然不明显,但有总比没有好

2. 比较鸡肋的新特性

  • DNF类型:实际用到的场景很少
  • 某些新函数:用处不大
  • 一些小的改进:感知不强

3. 需要注意的变化

  • 动态属性弃用:迁移成本高,要提前准备
  • 第三方包兼容性:升级前要检查所有依赖
  • 开发工具适配:IDE、静态分析工具都要升级
  • RC版本的稳定性:生产环境不要用RC版本

六、升级建议

如果你也想尝试PHP 8.2,给你几个建议。

1. 不要急着升级生产环境

PHP 8.2正式版刚发布的时候,不要急着升级生产环境。

  • 等几个月,让bug修复得差不多了
  • 等主要的第三方包都适配了
  • 等开发工具都支持了
  • 在测试环境充分验证后,再升级生产环境

2. 先在测试环境或个人项目尝试

可以先在测试环境或个人项目中尝试PHP 8.2:

  • 熟悉新特性
  • 发现兼容性问题
  • 积累升级经验
  • 为生产环境升级做准备

3. 检查第三方包兼容性

升级前,一定要检查所有第三方包的兼容性:

  • 看包的文档,是否支持PHP 8.2
  • 看包的issue,是否有PHP 8.2相关的问题
  • 不兼容的包,找替代方案或等待更新
  • 停止维护的包,考虑替换

4. 处理动态属性

动态属性弃用,是升级的最大障碍。

  • 扫描代码,找出所有动态属性的使用
  • 能声明属性的,都声明
  • 必须用动态属性的,加#[AllowDynamicProperties]
  • 第三方包的问题,升级或打补丁

5. 做好回滚准备

升级前,做好回滚准备:

  • 备份代码和数据
  • 保留旧版本的环境
  • 准备回滚脚本
  • 升级后密切监控,出问题及时回滚

七、写在最后

PHP 8.2,从入门到差点放弃,我经历了很多。

它有让人惊喜的新特性(只读类),也有让人头疼的兼容性问题(动态属性弃用、第三方包不兼容)。它不是完美的,但它代表了PHP的发展方向。

我的建议是:不要急,也不要怕。不急着在生产环境升级,但也不要因为有坑就完全放弃。可以先在测试环境或个人项目中尝试,积累经验,等时机成熟了再升级生产环境。

2022年了,PHP已经发展到8.x版本了。从PHP 5到PHP 7,再到PHP 8,每一次大版本升级,都有阵痛,但也都带来了进步。PHP 8.2也不例外。

最后,用一句话总结:"PHP 8.2有惊喜,也有坑。不要盲目升级,也不要因噎废食。先在测试环境尝试,做好准备,再升级生产环境。"

愿你的PHP升级,一帆风顺。