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 Ajax实现页面无刷新发表评论
Jan 02 PHP
利用discuz实现PHP大文件上传应用实例代码
Nov 14 PHP
php实现webservice实例
Nov 06 PHP
php实现基于微信公众平台开发SDK(demo)扩展的方法
Dec 22 PHP
php在线解压ZIP文件的方法
Dec 30 PHP
php实现插入数组但不影响原有顺序的方法
Mar 27 PHP
php实现统计网站在线人数的方法
May 12 PHP
php-beanstalkd消息队列类实例分享
Jul 19 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
thinkphp5 migrate数据库迁移工具
Feb 20 PHP
php设计模式之工厂方法模式分析【星际争霸游戏案例】
Jan 23 PHP
PHP代码加密的方法总结
Mar 13 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
15种PHP Encoder的比较
2007/03/06 PHP
Ajax PHP简单入门教程代码
2008/04/25 PHP
深入浅析Yii admin的权限控制
2016/08/31 PHP
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
PHP实现负载均衡的加权轮询方法分析
2018/08/22 PHP
js关闭当前页面(窗口)的几种方式总结
2013/03/05 Javascript
js阻止冒泡及jquery阻止事件冒泡示例介绍
2013/11/19 Javascript
php和js对数据库图片进行等比缩放示例
2014/04/28 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
JS实现显示当前日期的实例代码
2018/07/03 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
2018/08/20 Javascript
浅谈webpack和webpack-cli模块源码分析
2020/01/19 Javascript
详解JavaScript中的数据类型,以及检测数据类型的方法
2020/09/17 Javascript
vite2.0+vue3移动端项目实战详解
2021/03/03 Vue.js
jupyter安装小结
2016/03/13 Python
Python正规则表达式学习指南
2016/08/02 Python
Python基于高斯消元法计算线性方程组示例
2018/01/17 Python
对python模块中多个类的用法详解
2019/01/10 Python
从0开始的Python学习016异常
2019/04/08 Python
python使用opencv对图像mask处理的方法
2019/07/05 Python
用Anaconda安装本地python包的方法及路径问题(图文)
2019/07/16 Python
python处理document文档保留原样式
2019/09/23 Python
PyTorch加载自己的数据集实例详解
2020/03/18 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
关于Keras Dense层整理
2020/05/21 Python
Python matplotlib模块及柱状图用法解析
2020/08/10 Python
Python selenium环境搭建实现过程解析
2020/09/08 Python
Python 制作查询商品历史价格的小工具
2020/10/20 Python
读书活动实施方案
2014/03/10 职场文书
竞聘演讲稿开场白
2014/08/25 职场文书
个人三严三实对照检查材料思想汇报
2014/09/22 职场文书
乡镇镇长个人整改措施
2014/10/01 职场文书
南湾猴岛导游词
2015/02/09 职场文书
golang elasticsearch Client的使用详解
2021/05/05 Golang
浅谈CSS不规则边框的生成方案
2021/05/25 HTML / CSS
Python探索生命起源 matplotlib细胞自动机动画演示
2022/04/21 Python