编程 PHP 8.5 新语法实战:clone-with、管道操作符与 #[NoDiscard]

2026-09-06 21:10:28

PHP 8.5 新语法实战:clone-with、管道操作符与 #[NoDiscard]

PHP 8.5 于 2025-11-20 发布。下面是 clone-with、管道操作符 |>#[NoDiscard] 的语法笔记,代码均按 8.5 语法编写。

clone-with:克隆并覆盖属性

从 PHP 8.5 起,clone 可以按函数形式使用,并接受第二个可选参数:命名属性关联数组。键是属性名,值是覆盖后的新属性值。

readonly class Color
{
    public function __construct(
        public int $red = 0,
        public int $green = 0,
        public int $blue = 0,
        public int $alpha = 255,
    ) {}
}

$base = new Color(red: 1, green: 2, blue: 3);
$next = clone($base, ['red' => 200, 'alpha' => 128]);

echo $base->red;   // 1
echo $next->red;   // 200
echo $next->alpha; // 128

readonly 类来说,这就是一个内置的 with-er:想生成一个“只改几个属性”的新对象时,不必为每个字段手写 withRed()withAlpha(),也不必用 new self(...) 把全部旧值重列一遍。

注意语法是函数式调用:

$new = clone($obj, ['prop' => newValue]);

不是 clone $obj with [...],PHP 没有那种语法。

管道操作符 |>:组合 first-class callable

|> 把左侧值作为第一个参数传给右侧可调用对象。右侧推荐使用 first-class callable,例如 trim(...)

之前嵌套的写法:

$result = strtoupper(trim($input));

用管道后变成从左到右读:

$result = $input |> trim(...) |> strtoupper(...);

多步变换示例:

$input = "  PHP 8.5 pipe  \n";
$result = $input |> trim(...) |> strtolower(...) |> htmlspecialchars(...);
echo $result; // php 8.5 pipe

右侧要写 trim(...) 这样的 first-class callable,不是裸函数名 trim

#[NoDiscard]:返回值必须使用

在函数或方法上标注 #[NoDiscard] 后,调用方如果忽略其返回值,会触发告警。

#[NoDiscard]
function acquireLock(): bool
{
    return true;
}

acquireLock(); // 触发 warning:返回值未被使用

显式表示“我就是要放弃返回值”时,用 (void) 包住调用:

(void) acquireLock(); // 不触发 warning

适合用在那些“看返回值才能确认成功”的 API 上,例如加锁、写文件、保存数据。

生产建议

生产环境升级建议等 8.5.1。这些语法改动可以先在本地 PHP 8.5 开发环境验证。

参考:PHP 8.5.0 Release Announcement(中文)

复制全文 生成海报 PHP PHP8.5 语法 readonly 实战

推荐文章

程序员茄子在线接单