[php]对象的传值方式

对象的值传递和引用传递

<?php

class C1{
    var $p1 = 1;
}

//普通变量的值传递示例
$v1 =1 ;
$v2 = $v1;
$v1++;
echo "<br />v1 = $v1;v2 = $v2;";    //结果为v1 = 2;v2 = 1

//对象的值传递示例:
$o1 = new C1();
$o2 = $o1;
$o1->p1 = 2;
echo "<br />o1->p1={$o1->p1},o2->p1 = {$o2->p1}";  //o1->p1=2,o2->p1 = 2

//对象的引用类型传递:
$o3 = new C1();
$o4 = &$o3;
$o3->p1 = 2;
echo "<br />o3->p1={$o3->p1},o4->p1 = {$o4->p1}";  //o3->p1=2,o4->p1 = 2
?>

由上述例子中可见,对于对象传值,值传递方式和引用传递方式,对对象的数据的改变的结果是一样的。那它们的区别在哪?

我们要从对象的数据的存储方式来理解:

$o1 = new C1();    //创建一个对象o1,其存储结果如图:

这里写图片描述

这里,实际上,变量名$o1中,存储的数据只是一个“对象编号:#1”,这个对象编号才会指向对象数据new C1()。这个编号数据,我们是不能控制的,而是由系统内部分配的。

$o2 =$o1;    //此处发生了值传递,而对象的值传递,实际上是发生复制对象编号,结果如图:

这里写图片描述

我们可以看到,变量 o2 o1的“对象编号:#1”,它们的对象编号共同指向一个对象本身。此时:
o1->p1 =2;        //通过“对象编号:#1”修改了对象(new C1() )本身的内部数据。  
echo
o2->p1; //取得了“对象编号:#1”所指向的对象(new C1() )本身的内部数据。所以它们的值是一样的。

$o3 = new C1();	//又创建了一个对象$o3,其存储结果如图:

这里写图片描述

$o4 = &$o3;    //此处发生了引用传递,而对象的引用传递,实际上是发生指向同一个对象编号,结果如图:

这里写图片描述

$o3->p1 =2;        //通过“对象编号:#2”修改了对象(new C1() )本身的内部数据。
echo $o4->p1;  //取得了“对象编号:#2”所指向的对象(new C1() )本身的内部数据。所以它们的值是一样的。




对象的克隆(复制)

对象的克隆或复制,就是将目前已经存在的对象另外复制一份出来。类似于类的值传递,只不过克隆后,数据相同,对象编号不同。(当前相同,但此后一方的改变不会给另一方带来影响)

语法形式:

$obj2 = clone $obj1;
$obj2 = clone($obj1);

示例:

这里写图片描述

由于在克隆的时候,会将原有对象的属性,一模一样的复制一份。给我们带来的问题是,不能通过属性来区分哪个是原有对象,哪个是新对象。
解决方法是,对某些标识性的属性,进行修改即可。
方法一:
    克隆完成后,手动修改属性。

这里写图片描述

方法二:
    使用__clone()完成修改工作(推荐)。
    __clone():双下划线开头,是PHP内部使用的方法。其特点是:当进行克隆的时候,PHP内部核心会自动使克隆的新对象使用该方法。

这里写图片描述
__clone()方法不是必须存在,当它存在时(被定义),就一定会被自动调用。

深克隆
如果某个对象的属性值为另一个对象的时候,那么在克隆该对象时:
当PHP为浅克隆时,仅仅克隆当前对象,而不克隆属性的对象。结果为,新老对象共用同一个属性对象。
这里写图片描述这里写图片描述
结果:

两个英雄,共用一把武器!

如果需要将武器再次克隆,就要使用深克隆(由自己编程实现)。
通常利用__clone()方法。
这里写图片描述
在__clone()方法执行前,克隆时已经将新对象的武器属性克隆为其自己的武器属性值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值