编程 PHP 8.5 语言层改动:|> 管道、clone with、#[\NoDiscard] 与常量表达式闭包

2026-09-11 21:03:09

PHP 8.5 语言层改动:|> 管道、clone with、#[\NoDiscard] 与常量表达式闭包

PHP 8.5.0 已于 2025-11-20 发布。这里只梳理语言层面的新增与调整,信息来自 php.net 的 Release Announcement、New Features 手册与 php-src 的 UPGRADING,以及 zend.com 的《PHP 8.5: New Features and Deprecations》。

管道操作符 |>

|> 把可调用对象从左到右串起来,值在多个函数之间依次传递,不需要再声明中间变量。它替代的是那种由内向外读的嵌套调用,链式写法可以顺着念。

$result = "hello" |> strtoupper(...) |> strrev(...);

RFC:pipe-operator-v3(作者 crell)。

clone with

克隆对象时现在可以同时更新属性:clone() 接受一个可选的第二参数,是一个关联数组,给出要设置在克隆体上的具名属性及取值。对 readonly 属性较多的类,这类「with-er」模式写起来简单了不少。

#[\NoDiscard](void) 强转

给函数加上 #[\NoDiscard] 之后,PHP 会检查返回值是否被消费,没用到就告警。适合那种「返回值很重要、但很容易忘了用」的 API。

配套新增 (void) 强转,用来显式声明「这个值我故意不用」,可以抑制 #[\NoDiscard] 的告警,也可能抑制外部 IDE 与静态分析工具的同类诊断。

RFC:marking_return_value_as_important

常量表达式里的闭包与一等可调用

静态闭包和一等可调用(first-class callables)现在可以出现在常量表达式里,包括属性参数、属性默认值、参数默认值、常量与类常量。

另外注意:Closure 现在是 callable 的正式子类型。

RFC:closures_in_const_exprfcc_in_const_expr

其他语言层改动

  • 致命错误(例如超过最大执行时间)现在会带上 backtrace。RFC:error_backtraces_v2
  • 属性可加在编译期非类常量上,即 const MY_CONST = 1; 这种,而不是 define()#[\Deprecated] 现在也能用于常量和 trait。
  • #[\Override] 可以作用在属性上:引擎会校验父类或所实现接口中是否存在同名属性,不存在就编译报错。RFC:override_properties
  • 静态属性支持非对称可见性(asymmetric visibility)。RFC:static-aviz
  • 用构造器属性提升时可以声明 final 属性。RFC:final_promotion
  • 常量表达式里支持 cast。
  • 新增 #[\DelayedTargetValidation]:抑制核心/扩展属性用在无效目标上时的编译期错误,把报错推迟到运行时调用 ReflectionAttribute::newInstance()
  • OpCache 成为非可选部分,始终存在于二进制中。

弃用与移除(节选)

  • 非规范的标量类型 cast 名 (boolean)(double)(integer)(binary) 弃用。
  • mysqli_execute 别名弃用;curl_closecurl_share_closexml_parser_free 弃用(在 PHP >= 8.0 中它们已经是 no-op);socket_set_timeout 弃用;MHASH_* 常量全部弃用。
  • 非数字字符串的自增/自减弃用(Increment/Decrement operators RFC,Girgias)。
  • get_defined_functions()$exclude_disabled 参数弃用;array_key_exists()null 当数组偏移等用法弃用。
  • CLI/CGI 的 -z / --zend-extension 选项移除。
  • CLI 新增 php --ini=diff,输出非默认的 INI 指令。
复制全文 生成海报 PHP 8.5 语言特性

推荐文章

程序员茄子在线接单