PHP对象的深克隆方法 发布日期:2019-10-12 12:23:46     博主推荐★

先贴出来最终结果:

    public function deepClone($obj){
        $serObj = base64_encode(gzcompress(serialize($obj)));
        return unserialize(gzuncompress(base64_decode($serObj)));
    }

问题:为什么需要深克隆?因为我们有时候需要保持对象的属性,以及对象的属性【PS:该属性也是个对象】,这时候如果做赋值操作,那么就仅仅是当前对象的引用,那么A=B,B发生了变化,A自动发生了变化!
废话少说,看案例:

<?php
echo "<br><br>====================值赋值=====================<br><br>";
$old = 1;
$new = $old;
$new = 2;
echo "1、old:".$old."<br/>";//1、old:1
echo "2、new:".$new."<br/>";//2、new:2
$old = 3;
echo "1、old:".$old."<br/>";//1、old:3
echo "2、new:".$new."<br/>";//2、new:2

【总结】:值赋值很正常,和我们想的应该一样

echo "<br><br>=====================对象赋值====================<br><br>";
class objInside{
  public $attrInside = 1;
}
$old = new objInside();
$new = $old;
$new->attrInside = 2;
echo "1、old:".$old->attrInside."<br/>";//1、old:2
echo "2、new:".$new->attrInside."<br/>";//2、new:2
$old->attrInside = 3;
echo "1、old:".$old->attrInside."<br/>";//1、old:3
echo "2、new:".$new->attrInside."<br/>";//2、new:3

【总结】:对象赋值,是不是感觉有点不一样,这里其实是引用

echo "<br><br>=====================对象属性克隆====================<br><br>";
class objInsideClone{
  public $attrInside = 1;
}
$old = new objInsideClone();
$new = clone $old;
$new->attrInside = 2;
echo "1、old:".$old->attrInside."<br/>";//1、old:1
echo "2、new:".$new->attrInside."<br/>";//2、new:2
$old->attrInside = 3;
echo "1、old:".$old->attrInside."<br/>";//1、old:3
echo "2、new:".$new->attrInside."<br/>";//2、new:2

【总结】:对象clone,是我们想要的效果是吧,这里才是创建副本


echo "<br><br>=====================对象-对象属性克隆【没有colne函数】====================<br><br>";
class objInsideClone2{
  public $attrInside = 1;
}
class objOutsideClone2{
public $objInside2 = null;
public function __construct(){
  $this->objInside2 = new objInsideClone2();
}
//public function __clone(){//【没有colne函数】
//  $this->objInside2 = clone $this->objInside2;
//}
}
$old = new objOutsideClone2();
$new = clone $old;
$new->objInside2->attrInside = 2;
echo "1、old:".$old->objInside2->attrInside."<br/>";//1、old:2
echo "2、new:".$new->objInside2->attrInside."<br/>";//2、new:2
$old->objInside2->attrInside = 3;
echo "1、old:".$old->objInside2->attrInside."<br/>";//1、old:3
echo "2、new:".$new->objInside2->attrInside."<br/>";//2、new:3

【总结】:这里是不是有点懵逼,刚刚上面的demo,普通属性可以clone过来,但是为什么这里对象属性clone不过来呢?


echo "<br><br>=====================对象-对象属性克隆【有colne函数】====================<br><br>";
class objInsideClone2{
  public $attrInside = 1;
}
class objOutsideClone2{
public $objInside2 = null;
public function __construct(){
  $this->objInside2 = new objInsideClone2();
}
public function __clone(){//【有colne函数】
  $this->objInside2 = clone $this->objInside2;
}
}
$old = new objOutsideClone2();
$new = clone $old;
$new->objInside2->attrInside = 2;
echo "1、old:".$old->objInside2->attrInside."<br/>";//1、old:1
echo "2、new:".$new->objInside2->attrInside."<br/>";//2、new:2
$old->objInside2->attrInside = 3;
echo "1、old:".$old->objInside2->attrInside."<br/>";//1、old:3
echo "2、new:".$new->objInside2->attrInside."<br/>";//2、new:2

【总结】:现在明白了吧,如果要赋值对象属性,是需要添加__clone方法;这样是不是很复杂呢?因为很多时候我们利用的别人已经写好的东西
【大中型项目】都是好多年的代码了,要加起来恐怕没那么容易


超级宇宙无敌,深度克隆,通过序列化和反序列的方式:

    public function deepClone($obj){
        $serObj = base64_encode(gzcompress(serialize($obj)));
        return unserialize(gzuncompress(base64_decode($serObj)));
    }


参考文章:

1、https://blog.csdn.net/lovelion/article/details/7424620

2、https://www.cnblogs.com/taijun/p/4208008.html【PS:文章末尾有个错误,用json_encode无法独立完成该任务,当然序列化+json_encode是可以的】

    public function deepClone($obj){
        $serObj = json_encode(serialize($obj));
        return unserialize(json_decode($serObj));
    }//但是核心是序列化

3、针对参考2的错误【https://www.cnblogs.com/jiaoaozuoziji/p/7390021.html】见json_encode和序列化之间的区别
4、注意【gzcompress用法】https://blog.csdn.net/mangrandi/article/details/81780720


博文地址:https://blog.ahamu.cn/blog/detail.html?id=317
   
推荐文章
  • 1
    Linux服务器内存消耗过高
    2019/10/24
  • 2
    讲的比较好的B+树执行原理的文章
    2019/10/17
  • 3
    解决现有问题的方式方法
    2019/10/15
  • 4
    PHP对象的深克隆方法
    2019/10/12
  • 5
    ES演示文稿【二】
    2019/09/23
  • 6
    ES演示文稿
    2019/09/23
  • 7
    kibana正则表达式demo
    2019/09/23
  • 8
    聊天有序集合
    2019/09/23
  • 9
    分销员授权登陆逻辑思维导图
    2019/09/18
  • 10
    logstash配置记录
    2019/09/02
  • 11
    比较好用的过滤表情的正则
    2019/08/13
  • 12
    Linux中的screen命令使用
    2019/08/12
  • 13
    网站开发神奇【图片视频压缩网站】
    2019/07/24
  • 14
    windows安装sqlsrv遇到的问题
    2019/07/05
  • 15
    遇到服务空间有一部分没有使用的情况怎么扩展
    2019/06/20
  • 16
    阿里云磁盘空间扩容遇到的问题
    2019/06/20
  • 17
    关于用xhell连接linux虚拟机频繁出现Soc
    2019/06/15
  • 18
    nginx重置多级默认页
    2019/06/12
  • 19
    nginx完整日志记录笔记
    2019/06/10
  • 20
    HTTPS NGINX SSL_PROTOCOL
    2019/04/28
最喜标签
NYOJ 面试 AJAX ping CentOS 灰度算法 YII2