.NET程序员学PHP要注意的坑-OOP 浅复制 深复制 比较对象
2015-12-03 16:52
295 查看
<?php
/*
* PHP OOP
*
*
*/
class SubObject
{
public $title = "hi,i'm subObject";
}
class TestDeepCopy
{
public $subObj;
public $text = "xxxx";
public function __construct()
{
$this->subObj = new SubObject(); //包含一个子对象用来测试
}
}
/*
* 浅复制
*/
$o1 = new TestDeepCopy();
$o2 = $o1; //浅复制,同C#,2个引用指向同一个对象副本。
//======试试PHP垃圾回收机制==================
$t1 = new TestDeepCopy();
$t2 = new TestDeepCopy();
$t1 = $t2; //$t1现在变了,原来指向的对象已经没有人引用了,所以调用了__destruct析构函数
/*
* 深复制
* 并不是使用clone就是深复制,这和C#道理是一样的,深复制通常都是要类自己负责完成
*/
$test1 = new TestDeepCopy();
$test2 = clone $test1; //表面上是2个对象副本了,但内部引用的对象还是同一个
$test2->subObj->title="yes"; //改变了test2的子对象后, test1的也变了,说明是同一个
var_dump($test1);
var_dump($test2);
/*
* 深复制方案
* 1. __clone方法,在克隆一个对象的时候,被调用,利用它可以做一些:重置克隆出来的新对象的ID号,
* 毕竟每个对象的编号要唯一嘛,诸如此类。
* 也可以利用它,克隆对象包含的子对象,完成深复制
* 2. 序列化,反序列化,是递归的,所以子对象也同样深复制,但不会触发__clone方法,会触发:
* __sleep和__wakeup魔术方法
*/
class TestDeepCopy2
{
public $subObj;
public $text = "xxxx";
public function __construct()
{
$this->subObj = new SubObject(); //包含一个子对象用来测试
}
public function __clone()
{
echo '__clone ';
$this->subObj = new SubObject();
}
}
//
$d1 = new TestDeepCopy2();
$d2 = clone $d1;
$d2->subObj->title="OK"; //不会影响d1
var_dump($d1);
var_dump($d2);
//序列化方法
$ser1 = new TestDeepCopy2();
$ser2 = unserialize(serialize($ser1)); //没有触发__clone方法
$ser2->subObj->title="HOHO";
var_dump($ser1);
var_dump($ser2);
/*
* 比较对象是否相等:== ===
* == 同一类对象的所有成员相等。针对表达式的话,只比较值不管类型
* === 当且仅当是相同对象的引用。不仅考虑值还要考虑类型。
* 有了自定义__clone后,会打破相等。
*/
/*
* PHP OOP
*
*
*/
class SubObject
{
public $title = "hi,i'm subObject";
}
class TestDeepCopy
{
public $subObj;
public $text = "xxxx";
public function __construct()
{
$this->subObj = new SubObject(); //包含一个子对象用来测试
}
}
/*
* 浅复制
*/
$o1 = new TestDeepCopy();
$o2 = $o1; //浅复制,同C#,2个引用指向同一个对象副本。
//======试试PHP垃圾回收机制==================
$t1 = new TestDeepCopy();
$t2 = new TestDeepCopy();
$t1 = $t2; //$t1现在变了,原来指向的对象已经没有人引用了,所以调用了__destruct析构函数
/*
* 深复制
* 并不是使用clone就是深复制,这和C#道理是一样的,深复制通常都是要类自己负责完成
*/
$test1 = new TestDeepCopy();
$test2 = clone $test1; //表面上是2个对象副本了,但内部引用的对象还是同一个
$test2->subObj->title="yes"; //改变了test2的子对象后, test1的也变了,说明是同一个
var_dump($test1);
var_dump($test2);
/*
* 深复制方案
* 1. __clone方法,在克隆一个对象的时候,被调用,利用它可以做一些:重置克隆出来的新对象的ID号,
* 毕竟每个对象的编号要唯一嘛,诸如此类。
* 也可以利用它,克隆对象包含的子对象,完成深复制
* 2. 序列化,反序列化,是递归的,所以子对象也同样深复制,但不会触发__clone方法,会触发:
* __sleep和__wakeup魔术方法
*/
class TestDeepCopy2
{
public $subObj;
public $text = "xxxx";
public function __construct()
{
$this->subObj = new SubObject(); //包含一个子对象用来测试
}
public function __clone()
{
echo '__clone ';
$this->subObj = new SubObject();
}
}
//
$d1 = new TestDeepCopy2();
$d2 = clone $d1;
$d2->subObj->title="OK"; //不会影响d1
var_dump($d1);
var_dump($d2);
//序列化方法
$ser1 = new TestDeepCopy2();
$ser2 = unserialize(serialize($ser1)); //没有触发__clone方法
$ser2->subObj->title="HOHO";
var_dump($ser1);
var_dump($ser2);
/*
* 比较对象是否相等:== ===
* == 同一类对象的所有成员相等。针对表达式的话,只比较值不管类型
* === 当且仅当是相同对象的引用。不仅考虑值还要考虑类型。
* 有了自定义__clone后,会打破相等。
*/
相关文章推荐
- 一个关于if else容易迷惑的问题
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- Php Installing An Expansion
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- PHP 5.3.0 安装分析心得
- apache 环境下 php 的配置注意事项
- ASP.NET、ASP、PHP、JSP之间有什么区别?
- PHP VBS JS 函数 对照表
- C语言实现的统计php代码行数功能源码(支持文件夹、多目录)
- php xml 入门学习资料