PHP中浅复制与深复制的区别是什么
在 PHP 中,对象赋值和参数传递共同遵循两种复制方式:浅复制和深复制。
浅复制:
浅复制指的是将原对象的引用复制到新对象里,这意味着新对象与原对象共享同一个内存地址。当原对象属性值发生改变,新对象中的属性值也会跟随改变。
例如:
class Person {
public $name;
public $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
}
$person1 = new Person('John', 25);
$person2 = $person1; //浅复制
$person1->age = 30; //修改person1的属性age的值
echo $person2->age; //输出30,说明浅复制后修改person1对象相应属性的值,影响到新对象$person2中的相应属性的值。
深复制:
深复制指的是将原对象完全复制一份到新的内存地址中,新对象与原对象不共享任何内存地址。当原对象属性值发生改变,新对象中的属性值不会改变。
例如:
class Person {
public $name;
public $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
}
$person1 = new Person('John', 25);
//创建一个新的Person对象,将$person1属性值复制给它
$person2 = clone $person1; //深复制
$person1->age = 30; //修改person1的属性age的值
echo $person2->age; //输出25,说明深复制后不会受到复制前对象的改变影响。
浅复制的使用场景:
浅复制适合用于类中属性较少或者属性值类型为基本数据类型时,而不适合用于类中属性值类型为引用数据类型的情况。如下:
class Person {
public $name;
public $age;
public $address;
public function __construct($name, $age, $address) {
$this->name = $name;
$this->age = $age;
$this->address = $address;
}
}
$address = new Address('China', 'Beijing');
$person1 = new Person('John', 25, $address);
$person2 = $person1; //浅复制
$person1->address->city = 'Shanghai'; //修改$person1的属性address中的city值
echo $person2->address->city; //输出“Shanghai”,说明浅复制后修改$person1对象相应属性的值,影响到新对象$person2中的相应属性的值。
深复制的使用场景:
深复制适用于类中属性值类型为引用数据类型,或属性个数较多时,可以通过深复制来避免原对象属性值修改时影响到新对象的属性值。如下:
class Person {
public $name;
public $age;
public $address;
public function __construct($name, $age, $address) {
$this->name = $name;
$this->age = $age;
$this->address = $address;
}
}
$address = new Address('China', 'Beijing');
$person1 = new Person('John', 25, $address);
//通过clone操作符深复制Person对象
$person2 = clone $person1;
$person1->address->city = 'Shanghai'; //修改$person1的属性address中的city值
echo $person2->address->city; //输出“Beijing”,说明深复制后不会受到复制前对象的改变影响。
需要注意的是,对于PHP内置的数据类型,比如数组或字符串,赋值操作或函数参数传递都属于浅复制操作,因为PHP的底层实现就是这样的,变量存储的是数据的地址,变量操作只是简单地改变了数据的引用。因此,在处理引用数据类型的时候,需要特别注意复制的方式,确定使用浅复制还是深复制。
