php对象复制
引言
php对象复制可以通过clone
关键字完成,并且会调用__clone()
魔术方法。当对象被复制后,PHP 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性仍然会是一个指向原来的变量的引用。
浅复制
class A
{
public $name;
public function __construct() {
$this->name = 'A的name';
}
}
class B
{
public $name;
public $a;
public function __construct() {
$this->name = 'B的name';
$this->a = new A();
}
}
$bObj = new B();
$bCloneObj = clone $bObj;
$bCloneObj->a->name = '改变了A的name';
var_dump($bObj);
改变了$bCloneObj
对象引用的a
对象的name
属性后,原对象$bObj
的a
对象的name
属性也发生了变化,说明复制后的对象的属性扔指向了原来变量。
深复制
class A
{
public $name;
public function __construct() {
$this->name = 'A的name';
}
}
class B
{
public $name;
public $a;
public function __construct() {
$this->name = 'B的name';
$this->a = new A();
}
// 通过在__clone魔术方法中重新设置a可以实现深复制
public function __clone() {
$this->a = clone $this->a;
}
}
$bObj = new B();
$bCloneObj = clone $bObj;
$bCloneObj->a->name = '改变了A的name';
var_dump($bObj);
执行clone
后会执行__clone
魔术方法,我们可以利用这个特性在__clone
方法中克隆a对象,当然这里有个问题就是如果a又有对其他对象的引用,那么这里有一个递归的逻辑。其实__clone
方法目标是当完成属性的浅复制后可以对新对象的属性按照需求进行个性化设置。