PHP 5 使用 clone 關鍵字建立物件副本。預設行為為 淺拷貝:新物件擁有與原物件相同的屬性值(基本型別複製,資源/物件型別仍指向同一參考)。
__clone() 魔術方法在類別中定義 __clone() 可控制複製過程:
$this(新物件)與 $that(原物件,PHP 內部隱含)__clone(),PHP 不會自動複製任何屬性,必須手動從 $that 複製所需資料到 $this<?php
class ObjectTracker {
private static $nextSerial = 0;
private $id;
private $name;
public function __construct($name) {
$this->name = $name;
$this->id = ++self::$nextSerial;
}
public function __clone() {
// 複製時重新命名並分配新序號
$this->name = "Clone of $this->name";
$this->id = ++self::$nextSerial;
}
public function getId() { return $this->id; }
public function getName() { return $this->name; }
}
$ot = new ObjectTracker("Zeev's Object");
$ot2 = clone $ot;
echo $ot->getId() . " " . $ot->getName() . "\n"; // 輸出: 1 Zeev's Object
echo $ot2->getId() . " " . $ot2->getName() . "\n"; // 輸出: 2 Clone of Zeev's Object
?>
| 場景 | __clone 實作策略 |
|---|---|
| 資源管理(檔案句柄、DB 連線) | 複製時重新開啟資源,避免雙重關閉 |
| 巢狀物件結構 | 遞迴 clone 子物件,實現深拷貝 |
| 單例模式防複製 | 拋出例外或返回原實例 |
| 值物件 | 不實作 __clone,依賴預設淺拷貝即可 |
$that 僅供讀取,修改無效且不推薦__clone 時優先考慮不可變設計