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的库,结果发现很多东西
Dec 31 PHP
php zend 相对路径问题
Jan 12 PHP
vs中通过剪切板循环来循环粘贴不同内容
Apr 30 PHP
PHP获取网址的顶级域名函数代码
Sep 24 PHP
win7+apache+php+mysql环境配置操作详解
Jun 10 PHP
解决cPanel无法安装php5.2.17
Jun 22 PHP
修改ThinkPHP缓存为Memcache的方法
Jun 25 PHP
php中current、next与reset函数用法实例
Nov 17 PHP
Yii框架调试心得--在页面输出执行sql语句
Dec 25 PHP
PHP实现获取客户端IP并获取IP信息
Mar 17 PHP
php版微信公众平台接口参数调试实现判断用户行为的方法
Sep 23 PHP
PHP+MySQL实现消息队列的方法分析
May 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
四月新番又没了,《Re:从零开始的异世界生活》第二季延期至7月播出
2020/05/06 日漫
在PHP中利用XML技术构造远程服务(下)
2006/10/09 PHP
PHP数组实例总结与说明
2011/08/23 PHP
PHP中$_SERVER的详细参数与说明介绍
2013/10/26 PHP
用 Composer构建自己的 PHP 框架之使用 ORM
2014/10/30 PHP
分享PHP函数实现数字与文字分页代码
2015/07/28 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
PHP模板引擎Smarty内置变量调解器用法详解
2016/04/11 PHP
PHP面相对象中的重载与重写
2017/02/13 PHP
PHP学习记录之数组函数
2018/06/01 PHP
网站上面有这种切换效果
2006/06/26 Javascript
Javascript处理DOM元素事件实现代码
2012/05/23 Javascript
jquery Mobile入门—多页面切换示例学习
2013/01/08 Javascript
javascript中节点的最近的相关节点访问方法
2013/03/20 Javascript
jQuery找出网页上最高元素的方法
2015/03/20 Javascript
XML、HTML、CSS与JS的区别整理
2016/02/18 Javascript
js控制div层的叠加简单方法
2016/10/15 Javascript
Angular2+国际化方案(ngx-translate)的示例代码
2017/08/23 Javascript
微信小程序与后台PHP交互的方法实例分析
2018/12/10 Javascript
深入解析koa之中间件流程控制
2019/06/17 Javascript
vue中使用elementUI组件手动上传图片功能
2019/12/13 Javascript
vuex分模块后,实现获取state的值
2020/07/26 Javascript
简单掌握Python中glob模块查找文件路径的用法
2016/07/05 Python
python读取二进制mnist实例详解
2017/05/31 Python
Python3 sys.argv[ ]用法详解
2019/10/24 Python
python二维键值数组生成转json的例子
2019/12/06 Python
在 Linux/Mac 下为Python函数添加超时时间的方法
2020/02/20 Python
《鹬蚌相争》教学反思
2014/04/22 职场文书
2015年党员干部承诺书
2015/01/21 职场文书
2015年生产部工作总结范文
2015/05/25 职场文书
病房管理制度范本
2015/08/06 职场文书
导游词之千岛湖
2019/09/23 职场文书
导游词之山西关帝庙
2019/11/01 职场文书
python游戏开发之pygame实现接球小游戏
2022/04/22 Python
Spring Boot 实现 WebSocket
2022/04/30 Java/Android
flex布局中使用flex-wrap实现换行的项目实践
2022/06/21 HTML / CSS