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注入实例
Oct 09 PHP
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
Apr 18 PHP
php 清除网页病毒的方法
Dec 05 PHP
php面向对象全攻略 (四)构造方法与析构方法
Sep 30 PHP
PHP Stream_*系列函数
Aug 01 PHP
php 数据库字段复用的基本原理与示例
Jul 22 PHP
探讨GDFONTPATH能否被winxp下的php支持
Jun 21 PHP
使用array_map简单搞定PHP删除文件、删除目录
Oct 29 PHP
php经典算法集锦
Nov 14 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
Jun 29 PHP
基于swoole实现多人聊天室
Jun 14 PHP
tp5.1 框架路由操作-URL生成实例分析
May 26 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
40年前的这部特摄片恐龙特级克塞号80后的共同回忆
2020/03/08 日漫
php实现用户在线时间统计详解
2011/10/08 PHP
解决PHP4.0 和 PHP5.0类构造函数的兼容问题
2013/08/01 PHP
PHP调用JAVA的WebService简单实例
2014/03/11 PHP
PHP删除字符串中非字母数字字符方法总结
2019/01/20 PHP
从零开始学习jQuery (二) 万能的选择器
2010/10/01 Javascript
div+css+js实现无缝滚动类似marquee无缝滚动兼容firefox
2013/08/29 Javascript
[将免费进行到底]在Amazon的一年免费服务器上安装Node.JS, NPM和OurJS博客
2014/08/18 Javascript
使用JavaScript和C#中获得referer
2014/11/14 Javascript
JavaScript包装对象使用详解
2015/07/09 Javascript
jquery实现全选功能效果的实现代码
2016/05/05 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
JavaScript中无法通过div.style.left获取值的解决方法
2017/02/19 Javascript
Vue组件创建和传值的方法
2018/08/17 Javascript
VUE v-model表单数据双向绑定完整示例
2019/01/21 Javascript
11个教程中不常被提及的JavaScript小技巧(推荐)
2019/04/17 Javascript
使用Node.js写一个代码生成器的方法步骤
2019/05/10 Javascript
深入了解JavaScript代码覆盖
2019/06/13 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
微信小程序按钮点击动画效果的实现
2019/09/04 Javascript
ant-design-vue中tree增删改的操作方法
2020/11/03 Javascript
快速了解Python相对导入
2018/01/12 Python
Pipenv一键搭建python虚拟环境的方法
2018/05/22 Python
python利用dlib获取人脸的68个landmark
2019/11/27 Python
python 操作hive pyhs2方式
2019/12/21 Python
Python3如何在Windows和Linux上打包
2020/02/25 Python
Python实现CAN报文转换工具教程
2020/05/05 Python
Python requests模块安装及使用教程图解
2020/06/30 Python
Python 利用flask搭建一个共享服务器的步骤
2020/12/05 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
2021/01/24 Python
专门出售各种儿童读物的网站:Put Me In The Story
2016/08/07 全球购物
美国知名的旅游网站:OneTravel
2018/10/09 全球购物
家长对孩子评语
2014/01/30 职场文书
结婚喜宴主持词
2014/03/14 职场文书
食品药品安全责任书
2015/05/11 职场文书
海底两万里读书笔记
2015/06/26 职场文书