PHP对象的深、浅拷贝

PHP对象的深、浅拷贝

深浅拷贝定义

深拷贝

赋值时值完全复制 完全的copy 对其中一个作出改变 不会影响另一个
即 值传递

浅拷贝

赋值时 引用赋值 相当于取了一个别名 对其中一个修改 会影响另一个
即 引用传递

直接赋值对象

代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

class People
{
public $age;
public function __toString()
{
return "age: {$this->age}";
}
}

class Test
{
public $people;
}

$obj1 = new Test();
$obj1->people = new People();
$obj1->people->age = 2;
$obj2 = $obj1;
$obj2->people->age = 3;
echo "obj1: " . $obj1->people;
echo "<br />";
echo "obj2: " . $obj2->people;

输出结果

obj1: 3
obj2: 3

内存示意图

image.png

结论

  • PHP默认采用引用传递
  • $obj1 and $obj2指向同一地址空间
  • 对任一对象属性修改 对另一个对象都是可见的

clone对象 「浅拷贝」

代码片段

不存在引用变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

class People
{
public $age;
public function __toString()
{
return "age: {$this->age}";
}
}

class Test
{
public $people;
}

$obj1 = new Test();
$obj1->people = new People();
$obj1->people->age = 2;
$obj2 = clone $obj1;
$obj2->people->age = 3;
echo "obj1: " . $obj1->people;
echo "<br />";
echo "obj2: " . $obj2->people;

存在引用变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

class People
{
public $age;
public function __toString()
{
return "age: {$this->age}";
}
}

class Test
{
public $people;
}

$c = 2
$obj1 = new Test();
$obj1->people = new People();
$obj1->people->age = &$c;
$obj2 = clone $obj1;
$obj2->people->age = 3;
echo "obj1: " . $obj1->people;
echo "<br />";
echo "obj2: " . $obj2->people;

输出结果

不存在引用变量

obj1: 2
obj2: 3

存在引用变量

obj1: 3
obj2: 3

内存示意图

不存在引用变量

image.png

####

存在引用变量

image.png

结论

  • 当没有引用变量传递时 该克隆可实现对象的独立复制
  • 当存在引用变量传递时 引用变量无法实现独立 修改对另一变量可见
  • 为浅拷贝方式

clone对象 「深拷贝」

代码片段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php

class People
{
public $age;
public function __toString()
{
return "age: {$this->age}";
}
}

class Test
{
public $people;
public function __clone()
{
// 对对象属性也执行clone
$this->people = clone $this->people;
}
}

$obj1 = new Test();
$obj1->people = new People();
$obj1->people->age = 2;
$obj2 = clone $obj1;
$obj2->people->age = 3;
echo "obj1: " . $obj1->people;
echo "<br />";
echo "obj2: " . $obj2->people;

输出结果

obj1: 2
obj2: 3

内存示意图

不存在引用变量

image.png

存在引用变量

image.png

结论

  • 该克隆可实现对象的独立复制
  • 对任一对象属性修改 对另一个对象都是可见的
  • 为深拷贝方式
# PHP

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×