php之clone 复制对象以及__clone魔术方法

如果错误和不足请给予指出,谢谢~

(⊙_⊙)

在开始使用clone之前我们下先看以下一个小例子:

<?php 
//首先定义一个test一个类
class Testclass {
    //成员变量是$value1
    public $value1;
}
//随后new一个obj1
$obj1 = new Testclass();
//复制成员变量的值为qqq
$obj1->value1 = "qqq";
//我们使用赋值符号给左边obj2赋值obj1
$obj2 = $obj1;
//我们在这里把obj2的的value1复制为eee
$obj2->value1 ="eee";     
//随后我们打印出两者的值
var_dump($obj1);
echo '<br/>';
var_dump($obj2);

为了查看方便,我把那个解释写在了注释=。=。(这句话总感觉怪怪的)

我们运行一下,发现如下结果:
运行结果

是不是两者的值都是一样的?
那是因为(借用php手册的话就是):当对象被复制后,PHP 5 会对对象的所有属性执行一个浅复制(shallow copy)。所有的引用属性 仍然会是一个指向原来的变量的引用。

其实在这里就是obj1给了obj2它的地址,就和引用一样,obj2指向了obj1,所以导致两者所执行的操作将会收到影响。那么该如何解决这样情况呢?当然是使用clone了;列如下代码:

<?php 
//首先定义一个test一个类
class Testclass {
    //成员变量是$value1
    public $value1;
}
//随后new一个obj1
$obj1 = new Testclass();
//复制成员变量的值为qqq
$obj1->value1 = "qqq";
//在这里我们使用clone来赋值obj1
$obj2 =clone $obj1;
//我们在这里把obj2的的value1复制为eee
$obj2->value1 ="eee";     
//随后我们打印出两者的值
var_dump($obj1);
echo '<br/>';
var_dump($obj2);

注意看这一段代码:

$obj2 =clone $obj1;

在这里使用了clone,这样就会没事了,看如下运行结果:
运行结果

是否发现两者并没有相互影响呢?

好了,在这里已经完成了基本的clone的讲解了,现在我们来深入一下(抽根烟压压惊。。。 ( ´´ิ∀´ิ` ) )

我们接下来看看一个例子:

<?php 
//首先定义一个test一个类
class Testclass {
    //成员变量是$value1
    public $value1;
}
//在这里是定义了一个变量
$vlaue_1='bbj';
//随后new一个obj1
$obj1 = new Testclass();
//引用value_1的值,注意,是引用
$obj1->value1 = &$vlaue_1;
//在这里我们使用clone来赋值obj1
$obj2 =clone $obj1;
//我们在这里把obj2的的value1复制为eee
$obj2->value1 ="eee";     
//随后我们打印出两者的值
var_dump($obj1);
echo '<br/>';
var_dump($obj2);

我们的代码和之前的差不多,我们主要看这一行:

//引用value_1的值,注意,是引用
$obj1->value1 = &$vlaue_1;

注意在此是引用哟。
我们看下运行结果:
运行结果
是否发现我在obj2改变了value1值之后obj1的值也会改变?因为在这里obj1赋值成员变量的时候使用了&取址。将会成为一个引用的状态。那么我们如果想要把这个值不守clone出来的对象的值影响该怎么办呢?

那么在这里我们只需要在此clone一下这个成员变量就好了,该如何clone了?那么我们现在就可以使用我们的魔法方法__clone了。

首先我们来说说__clone()在什么状态下触发:

当我们有clone操作的时候将会除非这个类里面的__clone方法。那么把我们的成员变量在__clone方法里面clone一下就好了,如下代码演示:
注:clone只能用于对象克隆,对象复制。记住,如果你clone一个非对象变量将会报错no obj。。。
以下例子是我从网上找的一个例子,感觉不错,这里将用这个例子来讲解魔法方法__clone的使用:
本来这个是没有注释的,我顺便把解释丢到了里面,这样强制clone后就不会指向原来的对象了。

<?php 
class testClass
{
 public $str_data;//这里是一个非对象类型
 public $obj_data;//在这里这是一个对象,可以看下面将会给一个对象给他
//使用clone的时候触发
 public function __clone() {
   $this->obj_data = clone $this->obj_data;//这个对象将会被克隆,会被强制复制,这样就不会指向原来的对象了
 }
}
//new一个datatime对给datatimeobj
$dateTimeObj = new DateTime("2014-07-05", new DateTimeZone("UTC"));

$obj1 = new testClass();//new一个testclass
$obj1->str_data ="aaa"; //复制aaa
$obj1->obj_data = $dateTimeObj; //给obj_data一个对象datetimeobj

$obj2 = clone $obj1; //克隆obj1给obj2
var_dump($obj1);  // str_data:"aaa"  obj_data:"2014-07-05 00:00:00"
var_dump($obj2);  // str_data:"aaa"  obj_data:"2014-07-05 00:00:00"
$obj2->str_data ="bbb"; //obj2给一个值bbb给strdata
$obj2->obj_data->add(new DateInterval('P10D'));//objdata改变objdata的值

var_dump($obj1);  // str_data:"aaa"  obj_data:"2014-07-05 00:00:00"
var_dump($obj2);  // str_data:"aaa"  obj_data:"2014-07-15 00:00:00"
var_dump($dateTimeObj);  //"2014-07-05 00:00:00"

以上就是clone的使用方法了=。=。。。
如果错误请给予指出,谢谢~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

1_bit

你的余额交给我吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值