PHP 对象克隆中 $this 与 $that 指针的应用详解
在 PHP 对象克隆操作中,若需在克隆瞬间修改新对象的属性,可利用 __clone() 魔法方法。该方法内部提供了两个关键指针:$this 指向当前正在被创建的复本(新对象),$that 指向被克隆的原像(旧对象)。理解这一指针对比关系,是实现深度属性定制或重置的关键。
对象克隆的基本行为
使用 clone 关键字复制一个已存在的对象时,PHP 会创建一个全新的对象实例。默认情况下,新对象的属性值与原对象完全相同,这种操作称为“浅拷贝”。如果希望在克隆完成后改变新对象的状态,例如给克隆出的名字加上特定标记,就需要重写 __clone() 方法。
__clone() 中的指针映射
当 PHP 执行 p2 = clone p1; 时,内存中已经存在 p1 和新的 p2。此时调用 p2->__clone(),方法体内的变量含义如下:
$this:指向复本,即刚刚被分配内存空间的p2对象实例。对$this->xxx的赋值是对新对象属性的修改。$that:指向原像,即触发克隆操作的p1对象实例。读取$that->xxx是获取原对象的属性值。
第 1 步:定义包含属性的类结构
首先,建立一个带有多个属性的类。这里以 Person 为例,包含姓名、性别和年龄。构造函数用于初始化这些基础信息。
class Person {
var $name; // 人的名字
var $sex; // 人的性别
var $age; // 人的年龄
function __construct($name, $sex, $age) {
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}
function say() {
echo "我的名字叫:" . $this->name . " 性别:" . $this->sex . " 我的年龄是:" . $this->age . "<br>";
}
}
第 2 步:实现 __clone() 逻辑区分新老对象
在类中定义 __clone() 方法。该方法没有参数,依靠 $this 和 $that 进行交互。以下示例展示了如何将复本的名字修改为基于原名字的组合字符串。
function __clone() {
// $this 指的复本 p2,而 $that 是指向原本 p1
// 在此处改变复本的属性,不会影响原对象 p1
$this->name = "我是复制的" . $that->name;
}
第 3 步:执行克隆并验证结果
创建原始对象 $p1,然后通过 clone 生成 $p2。最后分别输出两者的状态,观察差异。
?php
$p1 = new Person("张三", "男", 20);
$p2 = clone $p1;
// 检查原对象
$p1->say();
// 检查克隆后的对象
$p2->say();
?>
运行上述代码,控制台将依次输出:
我的名字叫:张三 性别:男 我的年龄是:20
我的名字叫:我是复制的张三 性别:男 我的年龄是:20
可以看到,$p1 保持了原名,而 $p2 的名字在前缀上发生了变化,且年龄和性别未受干扰。这证明了在 __clone() 中操作 $this 能够独立控制新对象。
注意事项与排错
- 空指针保护:虽然标准 PHP 内核总是正确传递
$that,但在某些复杂的继承链或特殊扩展环境下,建议在使用$that前确保其所属的对象实例有效。 - 嵌套对象处理:如果类的属性中包含其他对象,
__clone()默认执行的是浅拷贝(即新对象的属性指向同一个子对象实例)。若需深拷贝,必须在__clone()中对嵌套对象再次调用clone。 - 不可变性检查:
$this和$that均为只读引用。你不能重新给$this赋值指向另一个不相关的对象,它始终锚定在当前克隆过程的上下文。
以上就是关于 PHP 中 $this 和 $that 指针在对象克隆中使用实型的详细内容,更多关于 PHP 面向对象编程技巧的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













