代码 PHP 8.6 升级自查笔记:三十项弃用里,哪些会改变现有代码的行为

2026-09-25 21:06:20

PHP 8.6 升级自查笔记:三十项弃用里,哪些会改变现有代码的行为

PHP 8.6 计划于 2026 年 11 月 19 日发布,变更规模比 8.5 更小:没有 JIT 变更,没有属性钩子(property hooks),没有联合类型——没有任何会重塑类编写方式的改动。这一版真正的主题是大约三十项弃用,它们都在为 PHP 9.0 的移除铺路。

新增内容只有两项值得一提:部分函数应用,以及 final readonly class Time\Duration(35 票赞成、1 票反对),让超时能够携带自己的单位。

下面按「会不会改变运行时行为、要不要动现有代码」来逐项核对。

会直接改变运行时行为

  • 从 finally 块中返回:已弃用,39 票对 3 票,是整个弃用 RFC 中票数最悬殊的一项。从 finally 中返回一直都非常令人困惑,是微妙 bug 的根源。
  • 从 __construct() 或 __destruct() 返回值:已弃用。
  • 把对象当数组传给函数:一些函数在接收数组的同时也接受对象,例如 array_walk()、array_walk_recursive()、deflate_init()、inflate_init()、zlib 与 bzip2 流过滤器参数、mb_convert_variables() 以及 http_build_query()。其内部实现方式可能导致微妙的 bug,甚至造成内存损坏。修复方式几乎总是在调用处加上 get_object_vars($obj)。
  • 通过反射在真实对象上进行静态调用:已弃用。
  • 使用错误类型设置 ReflectionProperty 值:已弃用。

需要在调用处改写

  • is_a() 与 is_subclass_of() 以字符串作为第一个参数已弃用(即 $allow_string 为 false 时)。
  • define() 的 $case_insensitive 参数已弃用。
  • 排序函数的 SORT_LOCALE_STRING 标志已弃用。
  • ArrayIterator 中那些继承而来却毫无意义的方法、SplFileObject 的 CSV 方法,以及不完整的 session_set_save_handler() 实现,同样已被弃用。

标识符与保留词汇

  • readonly 作为函数名已弃用(39 票对 1 票)。readonly 最初被允许用作函数名,是因为 WordPress 有一个同名函数,这是通过 PHP 词法分析器中的一个 hack 实现的。
  • is 与 let 作为标识符、namespace 作为类常量名,以及 _ 作为常量,均已被弃用。引擎正在保留词汇——尤其是 is,它被留作未来模式匹配之用。

函数级弃用

is_double、is_integer、is_long、doubleval、strcoll、metaphone、spl_classes、spl_object_hash、mysqli::stmt_init、mysqli_get_charset。

mb_ereg 系列:语义迁移,不是重命名

Oniguruma——mbstring 的 mb_ereg 系列背后的正则引擎——已于 2025 年 4 月 24 日停止上游维护。PHP 的回应是:8.6 中弃用,PHP 9.0 中移除。如果正在使用 mb_ereg()、mb_eregi()、mb_ereg_replace()、mb_regex_encoding() 及其同族函数,应转向 PCRE,即使用带 /u 修饰符的 preg_*。这是语义迁移,而不是重命名;两个引擎在足够多的细节上存在分歧,因此每迁移一个模式都应配套测试。

把弃用清单当路线图读

这些弃用项作为路线图来读异常清晰:内部开发者正在为模式匹配保留关键字,剥离一个失去维护的正则引擎,终结「对象当数组用」的时代,把警告变成异常,并收紧安全默认值。

复制全文 生成海报 PHP 版本升级 弃用 兼容性

推荐文章

程序员茄子在线接单