PHP中的浅复制与深复制的实例详解


Posted in PHP onOctober 26, 2017

PHP中的浅复制与深复制的实例详解

前言:

最近温习了一下Design Pattern方面的知识,在看到Prototype Pattern这一设计模式时,注意到其中涉及到一个浅复制与深复制的问题。这里来总结一下,提醒自己以后一定要多加注意。

自PHP5起,new运算符自动返回一个引用,一个 对象变量 已经不再保存整个对象的值,只是保存一个标识符来访问真正的对象内容。当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,另外一个变量跟原来的不是引用的关系,只是他们都保存着同一个标识符的拷贝,这个标识符指向同一个对象的真正内容。

这里举个栗子:

class Example1
{
  public $name;

  public function __construct($name)
  {
    $this->name = $name;
  }
}

$ex1 = new Example('test1');// $ex1->name现在是:test1
$ex2 = $ex1;// $ex2->name现在是:test1

$ex2->name = 'test2';// 这样修改一下之后,$ex1->name与$ex2->name都变为了:test2

通过上面这个例子,应该可以理解对象间引用的概念了,那么我们继续往下走,在php中提供了 clone 这个关键字来进行对象复制,还是用上面的类来演示一下:

$ex1 = new Example('test1');// $ex1->name现在是:test1
$ex2 = clone $ex1;//$ex2->name现在是:test1

$ex2->name = 'test2';//现在$ex1->name还是test1,而$ex2->name是test2

这里看到,通过clone之后,$ex1与$ex2是两个不同的对象,他们拥有各自的变量环境。但是这里需要注意,在这两个对象内部,拥有的是值类型的数据,如果是内部拥有的是引用类型,那么通过clone得到的新对象中的引用则仍然指向原引用。这里就引申出 浅复制 与 深复制 的概念:

浅复制: 使用clone来复制对象,这种复制叫做“浅复制“,被赋值对象的所有变量都还有与原来对象相同的值,而所有的对其他对象的引用都仍然指向原来的对象。

深复制:被复制的对象的所有的变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。

默认使用 clone 是进行一个浅复制,那么如何才能进行深复制呢?

方式一:利用__clone方法

public function __clone()
{
  $this->obj = new Obj();
}

这种方式非常直观,但是却有一个很麻烦的操作方式,就是当类中包含多个引用时,你就需要在__clone方法中逐个重新设置。而且还要处理一些循环引用的问题。是很复杂的。

方式二:利用串行化(冷藏与解冻)

$tmp = serialize($ex1);
$ex2 = unserialize($tmp);

这时候得到的$ex2就是一个全新的对象,这个过程在java中也叫作”冷藏“与”解冻“过程。

序列化是一个递归的过程,我们不需要理会被对象内部引用了多少个对象以及引用了多少层对象,我们都可以彻底的复制。方式二真的很黄很暴力,但是我很喜欢。

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
第四节 构造函数和析构函数 [4]
Oct 09 PHP
php 应用程序安全防范技术研究
Sep 25 PHP
PHP中的闭包(匿名函数)浅析
Feb 07 PHP
php结合curl实现多线程抓取
Jul 09 PHP
10款实用的PHP开源工具
Oct 23 PHP
Ajax实现对静态页面的文章访问统计功能示例
Oct 10 PHP
PHP 微信扫码支付源代码(推荐)
Nov 03 PHP
PHP实现普通hash分布式算法简单示例
Aug 06 PHP
PHP PDOStatement::setFetchMode讲解
Feb 03 PHP
PHP实现通过文本文件统计页面访问量功能示例
Feb 13 PHP
微信公众平台开发教程④ ThinkPHP框架下微信支付功能图文详解
Apr 10 PHP
PHP解决高并发问题
Apr 01 PHP
thinkPHP5实现数据库添加内容的方法
Oct 25 #PHP
thinkPHP5分页功能实现方法分析
Oct 25 #PHP
thinkPHP框架中执行原生SQL语句的方法
Oct 25 #PHP
php调用云片网接口发送短信的实现方法
Oct 25 #PHP
OAuth认证协议中的HMACSHA1加密算法(实例)
Oct 25 #PHP
Laravel学习教程之request validation的编写
Oct 25 #PHP
Yii2框架实现登录、退出及自动登录功能的方法详解
Oct 24 #PHP
You might like
一个PHP操作Access类(PHP+ODBC+Access)
2007/01/02 PHP
php设计模式 Prototype (原型模式)代码
2011/06/26 PHP
PHP备份数据库生成SQL文件并下载的函数代码
2012/02/05 PHP
php实现简单洗牌算法
2013/06/18 PHP
PHP实现的博客欢迎提示功能(很特别哦)
2014/06/05 PHP
PHP实现在数据库百万条数据中随机获取20条记录的方法
2017/04/19 PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
2017/07/03 PHP
JavaScript模块随意拖动示例代码
2014/05/27 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
Jquery 实现grid绑定模板
2015/01/28 Javascript
创建简单的node服务器实例(分享)
2017/06/23 Javascript
Vue动态组件实例解析
2017/08/20 Javascript
利用JS如何计算字符串所占字节数示例代码
2017/09/13 Javascript
webpack打包js的方法
2018/03/12 Javascript
js实现简单分页导航栏效果
2019/06/28 Javascript
微信小程序云函数使用mysql数据库过程详解
2019/08/07 Javascript
用js编写留言板
2020/03/17 Javascript
JavaScript实现五子棋小游戏
2020/10/26 Javascript
JavaScript使用setTimeout实现倒计时效果
2021/02/19 Javascript
apache部署python程序出现503错误的解决方法
2017/07/24 Python
关于Django ForeignKey 反向查询中filter和_set的效率对比详解
2018/12/15 Python
Python读写文件模式和文件对象方法实例详解
2019/09/17 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
python绘图模块之利用turtle画图
2021/02/12 Python
荟萃全球保健品:维他购
2018/05/09 全球购物
澳大利亚美容产品及化妆品在线:Activeskin
2020/06/03 全球购物
就业自荐书
2013/12/05 职场文书
儿子婚宴答谢词
2014/01/09 职场文书
财务总监岗位职责
2014/03/07 职场文书
市场总经理岗位职责
2014/04/11 职场文书
应用外语系自荐信
2014/06/26 职场文书
幼儿园大班教师个人工作总结
2015/02/05 职场文书
计生个人工作总结
2015/02/28 职场文书
2019年干货:自我鉴定
2019/03/25 职场文书
手写Spirit防抖函数underscore和节流函数lodash
2022/03/22 Javascript
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电