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 相关文章推荐
Win2000+Apache+MySql+PHP4+PERL安装使用小结
Oct 09 PHP
使用TinyButStrong模板引擎来做WEB开发
Mar 16 PHP
php变量范围介绍
Oct 15 PHP
MySql数据库查询结果用表格输出PHP代码示例
Mar 20 PHP
PHP发送短信代码分享
Aug 11 PHP
教你识别简单的免查杀PHP后门
Sep 13 PHP
PHP多维数组转一维数组的简单实现方法
Dec 23 PHP
PHP实现根据时间戳获取周几的方法
Feb 26 PHP
ThinkPHP实现图片上传操作的方法详解
May 08 PHP
浅析PHP数据导出知识点
Feb 17 PHP
解决Laravel 使用insert插入数据,字段created_at为0000的问题
Oct 11 PHP
PHP大文件分割分片上传实现代码
Dec 09 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创建多级目录代码
2008/06/05 PHP
使用PHP会话(Session)实现用户登陆功能
2013/06/29 PHP
PHP实现图片自动清理的方法
2015/07/08 PHP
php实现给一张图片加上水印效果
2016/01/02 PHP
PHP实现常用排序算法的方法
2020/02/05 PHP
javawscript 三级菜单的实现原理
2009/07/01 Javascript
javascript 命名规则 变量命名规则
2010/02/25 Javascript
WEB高性能开发之疯狂的HTML压缩
2010/06/19 Javascript
载入jQuery库的最佳方法详细说明及实现代码
2012/12/28 Javascript
响应式表格之固定表头的简单实现
2016/08/26 Javascript
js改变html的原有内容实现方法
2016/10/05 Javascript
Web前端开发之水印、图片验证码
2016/11/27 Javascript
jQuery实现模拟flash头像裁切上传功能示例
2016/12/11 Javascript
JS实现隔行换色的表格排序
2017/03/27 Javascript
Ajax异步文件上传与NodeJS express服务端处理
2017/04/01 NodeJs
label+input实现按钮开关切换效果的实例
2017/08/16 Javascript
js字符限制(字符截取) 一个中文汉字算两个字符
2017/09/12 Javascript
vue-scroller记录滚动位置的示例代码
2018/01/17 Javascript
Vue项目实现简单的权限控制管理功能
2019/07/17 Javascript
利用JavaScript的Map提升性能的方法详解
2019/08/14 Javascript
vue el-table实现自定义表头
2019/12/11 Javascript
python编程测试电脑开启最大线程数实例代码
2018/02/09 Python
django加载本地html的方法
2018/05/27 Python
Python判断有效的数独算法示例
2019/02/23 Python
分析运行中的 Python 进程详细解析
2019/06/22 Python
Django 用户认证组件使用详解
2019/07/23 Python
Django中的静态文件管理过程解析
2019/08/01 Python
Python3打包exe代码2种方法实例解析
2020/02/17 Python
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
优秀求职信范文分享
2013/12/19 职场文书
经典促销广告词大全
2014/03/19 职场文书
幼儿园课题方案
2014/06/09 职场文书
延安红色之旅心得体会
2014/10/07 职场文书
2019年市场部个人述职报告(三篇)
2019/10/23 职场文书
使用javascript解析二维码的三种方式
2021/11/11 Javascript
Vue自定义铃声提示音组件的实现
2022/01/22 Vue.js