首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP __clone 魔術方法中的 $this 與 $that 指標詳解

     編輯:PHP 綜合知識

背景

PHP 5 引入 __clone() 魔術方法,在 clone $obj 時自動調用。克隆預設為淺拷貝(引用型屬性共享同一對象)。若需在克隆後修改副本屬性,必須在 __clone() 中重新賦值。此時有兩個特殊指標:

  • $this:指向新建立的副本(克隆結果)。
  • $that:指向原始對象(被克隆者)。

代碼示範

<?php
class Person {
    public $name;
    public $sex;
    public $age;

    public function __construct($name, $sex, $age) {
        $this->name = $name;
        $this->sex = $sex;
        $this->age = $age;
    }

    public function say() {
        echo "我叫:{$this->name},性別:{$this->sex},年齡:{$this->age}
"; } public function __clone() { // $this 是副本,$that 是原本 $this->name = "我是複製的 " . $that->name; // $this->age = 30; // 也可修改其他屬性 } } $p1 = new Person("張三", "男", 20); $p2 = clone $p1; $p1->say(); // 原本 $p2->say(); // 副本(已在 __clone 中改名)

輸出結果

我叫:張三,性別:男,年齡:20
我叫:我是複製的 張三,性別:男,年齡:20

關鍵點總結

指標指向可修改用途
$this副本(新對象)是初始化副本專屬狀態(如重設 ID、時間戳、關聯對象)
$that原本(舊對象)否(僅讀)讀取原本屬性以計算副本初始值

實務應用場景

  • 實體識別重置:$this->id = null; 讓 ORM 視為新實體插入。
  • 關聯對象深拷貝:$this->address = clone $that->address;
  • 時間戳更新:$this->created_at = new DateTime();
  • 計數器遞增:$this->version = $that->version + 1;

常見誤區

  1. 以為 $that 是標準變數:它只在 __clone() 內部可用,且不可重新賦值($that = ... 會報錯)。
  2. 忘記呼叫父類 __clone():繼承鏈中需手動 parent::__clone();。
  3. 淺拷貝導致非預期共享:含有對象/資源屬性的類必須實現 __clone() 執行深拷貝。

進階:結合 __sleep / __wakeup

序列化/反序列化同樣會建立新對象,但不會觸發 __clone()。若需統一邏輯,可提取共用方法:

private function initCopy($source) {
    $this->id = null;
    $this->created_at = new DateTime();
    $this->address = clone $source->address;
}

public function __clone() { $this->initCopy($that); }
public function __wakeup() { $this->initCopy($this); /* 此處 $this 已是反序列化產生的新對象 */ }

總結

__clone() 中的 $this/$that 雙指標設計極具匠心:$this 面向未來(副本),$that 回顧過去(原本)。掌握此機制,即可精確控制對象複製行為,避免共享狀態導致的難以排查 Bug。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved