
PHP 中对象默认按引用传递,直接赋值会使两个变量指向同一内存地址;若需独立副本,必须使用 clone 关键字显式克隆对象,否则对副本的修改将影响原始对象。
php 中对象默认按引用传递,直接赋值会使两个变量指向同一内存地址;若需独立副本,必须使用 `clone` 关键字显式克隆对象,否则对副本的修改将影响原始对象。
在 PHP 中,对象(object)与其他标量类型(如 int、string、array)有本质区别:对象变量存储的是对象的引用(reference),而非值本身。这意味着当你执行 $varObjCopy = $varObj; 时,并未创建新对象,而是让 $varObjCopy 指向与 $varObj 完全相同的内存地址——二者共享同一份数据。
因此,以下代码的行为就清晰可解:
$varObj = (object) ['id' => '20', 'title' => 'Test ID 20', 'product' => '4']; var_dump($varObj->id); // 输出: string(2) "20" $varObjCopy = $varObj; // ❌ 仅复制引用,非复制对象 $varObjCopy->id = $varObj->product; var_dump($varObj->id); // 输出: string(1) "4" ← 原对象已被意外修改!
如你所见,$varObj->id 的值从 "20" 变为 "4",并非因为显式修改了它,而是 $varObjCopy 和 $varObj 实质上是同一个对象的两个别名。
✅ 正确做法:使用 clone 创建浅拷贝(shallow copy)clone 会实例化一个全新的对象,并逐个复制原始对象的非静态属性值(注意:对于对象类型的属性,仍为引用,除非该类定义了 __clone() 方法进行深度处理):
立即学习“PHP免费学习笔记(深入)”;
$varObj = (object) ['id' => '20', 'title' => 'Test ID 20', 'product' => '4']; var_dump($varObj->id); // string(2) "20" $varObjCopy = clone $varObj; // ✅ 创建独立副本 $varObjCopy->id = $varObj->product; var_dump($varObj->id); // string(2) "20" ← 原对象保持不变 var_dump($varObjCopy->id); // string(1) "4" ← 仅副本被修改
⚠️ 注意事项:
-
clone是浅拷贝:若对象属性本身是另一个对象(例如stdClass或自定义类实例),其引用仍会被复制,而非递归克隆。如需深度克隆,需在类中实现__clone()方法手动处理嵌套对象。 -
clone不调用__construct(),但会触发__clone()(如果存在),可用于重置资源、重新生成 ID 等。 - 数组、字符串、数字等标量属性在克隆后完全独立;资源类型(如 file handle)不能被克隆,需特殊处理。
? 小结:
在 PHP 中,“赋值即引用”是对象行为的核心特性。要实现“修改副本而不影响原对象”,唯一可靠且标准的方式就是显式使用 clone。切勿依赖赋值操作来“复制”对象——那只是复制了指针。



















