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 相关文章推荐
PHPMyadmin 配置文件详解(配置)
Dec 03 PHP
页面乱码问题的根源及其分析
Aug 09 PHP
php中限制ip段访问、禁止ip提交表单的代码分享
Aug 22 PHP
PHP解析目录路径的3个函数总结
Nov 18 PHP
php结合安卓客户端实现查询交互实例
May 05 PHP
php 静态属性和静态方法区别详解
Apr 09 PHP
删除PHP数组中的重复元素的实现代码
Apr 10 PHP
Yii框架实现图片上传的方法详解
May 20 PHP
基于Laravel5.4实现多字段登录功能方法示例
Aug 11 PHP
PHP排序算法之直接插入排序(Straight Insertion Sort)实例分析
Apr 20 PHP
php多进程并发编程防止出现僵尸进程的方法分析
Feb 28 PHP
YII2框架使用控制台命令的方法分析
Mar 18 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
如何过滤高亮显示非法字符
2006/10/09 PHP
Excel数据导入Mysql数据库的实现代码
2008/06/05 PHP
PHP crypt()函数的用法讲解
2019/02/15 PHP
Laravel 6 将新增为指定队列任务设置中间件的功能
2019/08/06 PHP
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
js使用setTimeout实现定时炸弹的方法
2015/04/10 Javascript
jQuery实现Meizu魅族官方网站的导航菜单效果
2015/09/14 Javascript
Jquery插件easyUi实现表单验证示例
2015/12/15 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
Vue CLI3搭建的项目中路径相关问题的解决
2018/09/17 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
javascript实现拖拽碰撞检测
2020/03/12 Javascript
js this 绑定机制深入详解
2020/04/30 Javascript
vue+node 实现视频在线播放的实例代码
2020/10/19 Javascript
如何在现代JavaScript中编写异步任务
2021/01/31 Javascript
javascript实现固定侧边栏
2021/02/09 Javascript
[01:11:32]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
python获取各操作系统硬件信息的方法
2015/06/03 Python
Python图像灰度变换及图像数组操作
2016/01/27 Python
对python中UDP,socket的使用详解
2019/08/22 Python
python爬虫 线程池创建并获取文件代码实例
2019/09/28 Python
在python中修改.properties文件的操作
2020/04/08 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
2020/11/02 Python
在HTML5中使用MathML数学公式的简单讲解
2016/02/19 HTML / CSS
HTML5输入框下拉菜单功能的示例代码
2020/09/08 HTML / CSS
澳大利亚吉他在线:Artist Guitars
2017/03/30 全球购物
Omio葡萄牙:全欧洲低价大巴、火车和航班搜索和比价
2019/02/09 全球购物
毕业生自我推荐
2013/11/04 职场文书
青春演讲稿范文
2014/05/08 职场文书
高中生打架检讨书1000字
2015/02/17 职场文书
中学生社会实践教育活动总结
2015/05/06 职场文书
2015年暑假生活总结
2015/07/13 职场文书
同学会演讲稿
2019/04/02 职场文书
MySQL快速插入一亿测试数据
2021/06/23 MySQL
JavaScript数组 几个常用方法总结
2021/11/11 Javascript
Python机器学习实战之k-近邻算法的实现
2021/11/27 Python