1 简介
-
php中,普通类型(包括array)为值拷贝;对象是引用(实质是拷贝了对象标识符,通过它可以访问到真正的对象,即
new class
时便是引用了) -
php5之后,=、做参数(无论是否带前置&)都是对class的引用(浅拷贝)
-
推荐用序列化深拷贝:unserialize(serialize($one))、json_decode(json_encode($one))
2 示例
1. 综合测试
<?php
// 下面列举三种情况:
// 1.对象做参数,或者被use
class Person{
public $name = "";
public function __construct($name){
$this->name = $name;
}
}
$aman = new Person('man');
function change( $p){
$p->name = 'lucy';
}
// 浅拷贝
change($aman);
echo $aman->name, "\n"; //lucy
// 2.数组
$stu = array(
'name' => 'lilei',
'sex' => 'male'
);
// 普通类型深拷贝
function foo($arr){
$arr['name'] = 'hanmeimei';
return $arr;
}
foo($stu);
var_dump($stu);
// 3.对象数组
$people = array(
'a' => new Person("aaaaa"),
'b' => new Person("bbbbb"),
);
// 值为对象,浅拷贝
function changeOne($arr){
$arr['a']->name = 'lucy2';
}
changeOne($people);
var_dump($people);
2. 对类进行集中测试
<?php
class Test {
public $f = "first";
}
class TestOne {
public $a = 1;
public $ac = null;
public function __construct()
{
$this->ac = new Test();
}
// __clone时需要修改的代码
public function __clone()
{
$this->ac = clone $this->ac;
}
}
$one = new TestOne();
echo "原值: ", $one->a, " ", $one->ac->f, "\n";
// =赋值:完全浅拷贝:$one的普通属性、class属性
//$two = $one;
//$two->a = 2;
//$two->ac->f = "second";
//echo "=赋值:", $one->a, " ", $one->ac->f, "\n";
// clone:部分浅拷贝:深拷贝$one的普通属性、浅拷贝class属性
//$three = clone $one;
//$three->a = 2;
//$three->ac->f = "second";
//echo "clone:", $one->a, " ", $one->ac->f, "\n";
// __clone添加逻辑:完全深拷贝,依赖编码(有嵌套的问题:类属性里面还有类属性,不推荐这样):$one的普通属性、class属性
//$four = clone $one;
//$four->a = 2;
//$four->ac->f = "second";
//echo "__clone:", $one->a, " ", $one->ac->f, "\n";
// serialize\json序列化赋值:完全深拷贝,$one的普通属性、class属性
//$five = unserialize(serialize($one));
//$five->a = 2;
//$five->ac->f = "second";
//echo "serialize:", $one->a, " ", $one->ac->f, "\n";
$five = json_decode(json_encode($one));
$five->a = 2;
$five->ac->f = "second";
echo "serialize:", $one->a, " ", $one->ac->f, "\n";