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 相关文章推荐
PHP+MySQL5.0中文乱码解决方法
Nov 20 PHP
PHP iconv 函数转gb2312的bug解决方法
Oct 11 PHP
php防止站外远程提交表单的方法
Oct 20 PHP
php禁止浏览器使用缓存页面的方法
Nov 07 PHP
thinkphp模板用法和内容输出实例
Nov 28 PHP
浅析PHP中Session可能会引起并发问题
Jul 23 PHP
详解Yii实现分页的两种方法
Jan 14 PHP
PHPTree――php快速生成无限级分类
Mar 30 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
Jul 21 PHP
Laravel框架实现定时发布任务的方法
Aug 16 PHP
php curl操作API接口类完整示例
May 21 PHP
PHP实现发送微博消息功能完整示例
Dec 04 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
关于js与php互相传值的介绍
2013/06/25 PHP
Zend Framework教程之Application用法实例详解
2016/03/14 PHP
php简单计算年龄的方法(周岁与虚岁)
2016/12/06 PHP
php实现微信企业转账功能
2018/10/02 PHP
疯掉了,尽然有js写的操作系统
2007/04/23 Javascript
ExtJS 工具栏 分页事件参数
2010/03/05 Javascript
jQuery 自动增长的文本输入框实现代码
2010/04/02 Javascript
js打印纸函数代码(递归)
2010/06/18 Javascript
HTML页面滚动时获取离页面顶部的距离2种实现方法
2013/09/05 Javascript
PHP实现的各种中文编码转换类分享
2015/01/23 Javascript
javascript中类的定义方式详解(四种方式)
2015/12/22 Javascript
利用JS屏蔽页面中的Enter按键提交表单的方法
2016/11/25 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
2017/01/22 Javascript
js手机号4位显示空格,银行卡每4位显示空格效果
2017/03/23 Javascript
Vue学习之路之登录注册实例代码
2017/07/06 Javascript
AngularJS中table表格基本操作示例
2017/10/10 Javascript
ionic选择多张图片上传的示例代码
2017/10/10 Javascript
Angular利用trackBy提升性能的方法
2018/01/26 Javascript
浅入深出Vue之自动化路由
2019/08/06 Javascript
Vue+ElementUI 中级联选择器Bug问题的解决
2020/07/31 Javascript
[03:53]2016国际邀请赛中国区预选赛第三日TOP10精彩集锦
2016/06/29 DOTA
Python命令行解析模块详解
2018/02/01 Python
python-docx修改已存在的Word文档的表格的字体格式方法
2018/05/08 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
django中上传图片分页三级联动效果的实现代码
2019/08/30 Python
Python dict和defaultdict使用实例解析
2020/03/12 Python
Python如何获取文件指定行的内容
2020/05/27 Python
python 获取域名到期时间的方法步骤
2021/02/10 Python
ECCO爱步官方旗舰店:丹麦鞋履品牌
2018/01/02 全球购物
NIHAOMARKET官方海外旗舰店:意大利你好华人超市
2018/01/27 全球购物
波兰补充商店:Muscle Power
2018/10/29 全球购物
学校纪律作风整改措施思想汇报
2014/10/11 职场文书
2014年民主评议党员工作总结
2014/12/02 职场文书
出纳岗位职责
2015/01/31 职场文书
药店营业员岗位职责
2015/04/14 职场文书
创业计划书之o2o水果店
2019/08/30 职场文书