PHP 对象克隆中 $this 与 $that 指针的应用详解

Ivy
Ivy
发布时间:2026-10-14 | 2人浏览过
原创

在 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 面向对象编程技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表