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 相关文章推荐
实现树状结构的两种方法
Oct 09 PHP
深入Memcache的Session数据的多服务器共享详解
Jun 13 PHP
PHP文件上传主要代码讲解
Sep 30 PHP
php与java通过socket通信的实现代码
Oct 21 PHP
PHP CURL获取返回值的方法
May 04 PHP
laravel安装和配置教程
Oct 29 PHP
php有效防止同一用户多次登录
Nov 19 PHP
thinkPHP中分页用法实例分析
Dec 26 PHP
php基于curl实现的股票信息查询类实例
Nov 11 PHP
一次因composer错误使用引发的问题与解决
Mar 06 PHP
PHP PDO和消息队列的个人理解与应用实例分析
Nov 25 PHP
详解PHP Swoole与TCP三次握手
May 27 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学习之 认清变量的作用范围
2010/01/26 PHP
提高define性能的php扩展hidef的安装和使用
2011/06/14 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
Jquery 获得服务器控件值的方法小结
2010/05/11 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
node.js中使用node-schedule实现定时任务实例
2014/06/03 Javascript
js中document.write的那点事
2014/12/12 Javascript
JQuery实现展开关闭层的方法
2015/02/17 Javascript
50 个 jQuery 插件可将你的网站带到另外一个高度
2016/04/26 Javascript
js实现点击每个li节点,都弹出其文本值及修改
2016/12/15 Javascript
微信小程序 两种为对象属性赋值的方式详解
2017/02/23 Javascript
javascript数据结构之多叉树经典操作示例【创建、添加、遍历、移除等】
2018/08/01 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
2020/04/14 Javascript
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
[01:36:57]【09DOTA2第一视角】小骷髅
2014/04/16 DOTA
[59:08]Ti4 冒泡赛第二天 NEWBEE vs Titan 2
2014/07/15 DOTA
[01:02:54]完美世界DOTA2联赛PWL S2 FTD vs GXR 第一场 11.22
2020/11/26 DOTA
python实现在字符串中查找子字符串的方法
2015/07/11 Python
Python 实现在文件中的每一行添加一个逗号
2018/04/29 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
influx+grafana自定义python采集数据和一些坑的总结
2018/09/17 Python
pycharm使用matplotlib.pyplot不显示图形的解决方法
2018/10/28 Python
python3实现zabbix告警推送钉钉的示例
2019/02/20 Python
详解Python3网络爬虫(二):利用urllib.urlopen向有道翻译发送数据获得翻译结果
2019/05/07 Python
使用Pyhton集合set()实现成果查漏的例子
2019/11/24 Python
使用Pandas的Series方法绘制图像教程
2019/12/04 Python
new_zeros() pytorch版本的转换方式
2020/02/18 Python
Python爬虫实例——scrapy框架爬取拉勾网招聘信息
2020/07/14 Python
会计岗位职责
2013/11/08 职场文书
自荐书模板
2013/12/15 职场文书
酒店管理求职信
2014/06/09 职场文书
个人授权委托书
2014/09/15 职场文书
复试通知单模板
2015/04/24 职场文书
MySQL中使用or、in与union all在查询命令下的效率对比
2021/05/26 MySQL
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis
Pygame如何使用精灵和碰撞检测
2021/11/17 Python