php深克隆和浅克隆

先来看下php对克隆的定义:

      你可能会想复制一个新的对象,保持所有属性与原来的对象的属性相同, 但必须是一个新的对象(因为如果不是新的对象,那么一个对象中的改变就会影响到另一个对象)。还有一种情况: 如果对象A中保存着对象B的引用,当你复制对象A时,你想其中使用的对象不再是对象B而是B的一个副本,那么 你必须得到对象A的一个副本。

意思就是复制完以后的对象你所看到的属性神马的可能没有变化,但是却是一个新的对象了。根据这个定义来定义两个简单的类来看下效果:

  class A{
  
    public $name='小名';
public $age = 19;
  
  }
  $a = new A;     
  $b = clone $a;     //这里是对$a的复制,复制对象的语法是$copy_of_object = clone $object;
 
  $a->name = "小李";   
  var_dump($a);
  echo "<br/>";
  var_dump($b);

输出结果如下:

object(A)#1 (2) { ["name"]=> string(6) "小李" ["age"]=> int(19) } 
object(A)#2 (2) { ["name"]=> string(6) "小名" ["age"]=> int(19) }

通过结果我们可以看出object(A)#1这个指的是打印$a所显示结果,而object(A)#2,虽然都是类A的对象,但是一个编号是1,一个编号是2,完全是两个类,而且当我复制完成后,改变其中一个对象的值,不会影响另外的一个对象的值。这种复制方式被称作为浅克隆。其实也就是通过一个关键字clone搞定的。不过如果想让复制后的对象和被复制的对象有所差别,可以使用魔术方法__clone()来完成。也就是在类里面加上一个方法(比如我想让复制后的对象年龄为20):public function __clone(){$this->age = 20;}

__clone()魔术方法会在  $b = clone $a;   的时候自动调用,复制对象A的时候同时改变了它的$age的值。

    这种浅克隆只能将当前的属性进行克隆,但是如果当前的属性是对象的时候,浅克隆就满足不了我们的需求了,这时候就需要用到深克隆,所谓的深克隆就是对象属性如果为对象,则将其生成克隆副本。在__clone()的方法的基础上,将类型为对象的属性进行克隆。再其基础上更改如下:

  class A{
  
    public $name='小名';
public $age = 19;
public $obj;     //这个属性类型为对象


public function __clone(){

 $this->age = 20;
}
  
  }


  class  B{
  
    public $name = '酱油';
  }


  $a = new A; 
  $a->obj = new B;    //这里是以B作为$obj的类的定义,将B实例化,对象保存在$a->obj
  $b = clone $a;     //这里是对$a的复制,复制对象的语法是$copy_of_object = clone $object;
 
  $a->name = "小李";   
  var_dump($a);
  echo "<br/>";
  var_dump($b);

结果如下:

object(A)#1 (3) { ["name"]=> string(6) "小李" ["age"]=> int(19) ["obj"]=> object(B)#2 (1) { ["name"]=> string(6) "酱油" } } 
object(A)#3 (3) { ["name"]=> string(6) "小名" ["age"]=> int(20) ["obj"]=> object(B)#2 (1) { ["name"]=> string(6) "酱油" } }

这里可以看到obj属性保存的对象明显是一个对象(都为object(B)#2

但是如果我们想在复制的时候让$obj这个对象也重新复制成一个新的对象,那么这个时候只需要改动__clone()方法

public function __clone(){

 $this->age = 20;
 $this->obj = new $this->obj;   //这里在clone $a 的时候,会自动调用__clone(),会将$obj所保存的对象也clone一个     副本
}

结果如下:

object(A)#1 (3) { ["name"]=> string(6) "小李" ["age"]=> int(19) ["obj"]=> object(B)#2 (1) { ["name"]=> string(6) "酱油" } } 
object(A)#3 (3) { ["name"]=> string(6) "小名" ["age"]=> int(20) ["obj"]=> object(B)#4 (1) { ["name"]=> string(6) "酱油" } }

至此,对象的复制才算完成。



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值