PHP 物件預設採用引用賦值,__clone() 魔術方法正是為了解決物件複製時的共享引用問題而設計。
class Account {
public $balance = 200;
public function setId($id) { $this->id = $id; }
}
class Person {
public $name;
public $age;
public $account;
public function __construct($name, $age, Account $account) {
$this->name = $name;
$this->age = $age;
$this->account = $account;
}
}
$account = new Account();
$account->setId(4);
$p1 = new Person('tom', 33, $account);
$p2 = clone $p1; // 淺拷貝
$p2->account->balance += 500;
// $p1->account->balance 也會變成 700!
複製後 $p2 的 account 屬性仍指向同一個 Account 實例,修改任一物件的帳戶餘額都會影響另一個。
class Person {
// ... 其他屬性與方法
public function __clone() {
$this->account = clone $this->account; // 顯式複製引用物件
}
}
關鍵原則:若物件屬性包含其他物件引用,且不希望被共享,必須在 __clone() 中顯式 clone 這些引用物件。 這是 PHP 物件導向開發中必須掌握的記憶體管理細節。