php 8.5 引入 clone with 语法,允许克隆时直接设置 public 属性,如 clone $obj with ['prop' => $val];它在 __clone() 执行后赋值,仅限 php 8.5+,不兼容 8.4。

PHP 8.4 并未引入 clone with 语法。该特性是在 PHP 8.5 中正式发布的(2025年11月20日公告确认),不是 8.4 的功能。
PHP 8.5 的 clone with 用法
它允许你在克隆对象的同时,直接覆盖或设置部分属性,无需先 clone 再逐个赋值,也不依赖 __clone() 方法做初始化。
- 语法为:
clone $obj with [ 'prop' => $newVal, 'other' => $other ] - 只支持 public 属性;protected/private 属性不可通过此语法修改
- 底层仍会触发
__clone()(如果定义了且是 public),但with部分的赋值发生在 __clone 执行之后 - 不改变原对象,只影响新克隆出的对象实例
实际写法示例
假设有一个用户类:
class User {
public string $name;
public int $age;
public ?string $status = 'active';
public function __construct(string $name, int $age) {
$this->name = $name;
$this->age = $age;
}
}
$u1 = new User('Alice', 28);
$u2 = clone $u1 with ['age' => 29, 'status' => 'pending'];
var_dump($u1->age, $u2->age); // 28, 29
var_dump($u1->status, $u2->status); // 'active', 'pending'
?>
和 __clone() 的协作关系
如果你同时定义了 public function __clone(),它仍会被调用 —— 但注意执行顺序:
- 先完成默认浅拷贝
- 再执行
__clone()方法体内的逻辑 - 最后应用
with [...]中的属性赋值(会覆盖 __clone 中已设的同名属性)
因此,若需在克隆时重置 ID、时间戳等字段,仍应在 __clone() 中处理;而业务态临时覆盖(如“复制会话并标记为草稿”)更适合用 clone ... with 一行解决。
兼容性与注意事项
该语法仅在 PHP 8.5+ 可用。低版本(包括 8.4)使用会报解析错误 Parse error: syntax error。
- 不能用于内部类(如
SplFixedArray)或明确禁止克隆的类 - 数组键必须是字符串字面量,不支持变量或表达式:
['name' => $v]✅,[$key => $v]❌ - 不支持方法调用或复杂表达式作为值,仅接受标量、数组、null、对象字面量(PHP 8.5+ 支持有限对象字面量)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











