PHP对象赋值与克隆
在php5 的对象编程经常提到的一个关键点是“默认情况下对象是通过引用传递的”。但其实这不是完全正确的。下面通过一些例子来说明。
php的引用是别名,就是两个不同的变量名字指向相同的内容。在php5,一个对象变量已经不再保存整个对象的值。只是保存一个标识符来访问真正的对象内容。 当对象作为参数传递,作为结果返回,或者赋值给另外一个变量,另外一个变量跟原来的不是引用的关系,只是他们都保存着同一个标识符的拷贝,这个标识符指向同一个对象的真正内容。
通俗说:普通的赋值操作只是传递了索引,只有在清除传值对象的时候,才会发生写时复制
<?php
//深入理解PHP对象赋值
echo '<pre>';$obj = new StdClass;
$obj->name = 'Pig';
var_dump($obj); //object(stdClass)#1 (1) { ["name"]=> string(3) "Pig" }$copy = $obj; // $obj ,$copy都是new StdClass返回的同一个标识符的拷贝
var_dump($copy); //object(stdClass)#1 (1) { ["name"]=>string(3) "Pig" }$objRef = &$obj; // 此时会将$obj转换成引用,然后赋值给$objRef,因此$obj,$objRef都为引用
var_dump($objRef); //object(stdClass)#1 (1) { ["name"]=>string(3) "Pig" }$objClone = clone $obj; //新空间
$obj->name = 'After Clone';
var_dump($objClone); //object(stdClass)#1 (1) { ["name"]=>string(3) "Pig" }
var_dump($obj); //object(stdClass)#1 (1) { ["name"]=>string(11) "After Clone" }//unset是删除引用效果
$nameRef = &$obj->name; //$obj->name被转换成引用(& string),然后赋给$nameRef
var_dump($obj); //object(stdClass)#2 (1) { ["name"]=>&string(11) "After Clone" }
unset($nameRef); //删除引用
var_dump($obj); //object(stdClass)#1 (1) { ["name"]=>string(11) "After Clone" }//null是赋值效果
$nameRef = &$obj->name; //恢复name的引用
var_dump($obj); //object(stdClass)#2 (1) { ["name"]=>&string(11) "After Clone" }
$nameRef = null;
var_dump($obj); //object(stdClass)#2 (1) { ["name"]=>&NULL }unset($objRef); //仅仅删除了引用
var_dump($obj); //object(stdClass)#1 (1) { ["name"]=>&NULL }$objRef = &$obj; //恢复对象引用
$obj->name = 'Lucy';
$obj = null; //赋值$obj为null,$obj只是new StdClass的标识拷贝,不会影响其内容。//$objRef做为$obj的引用,会同时被赋值null//等价 $objRef = null;var_dump($obj,$copy,$objRef,$objClone);
// NULL,
// object(stdClass)#1 (1) { ["name"]=>&string(4) "Lucy" },
// NULL,
// object(stdClass)#1 (1) { ["name"]=>string(3) "Pig" }?>
对象克隆
有的时候我们需要在一个项目里面使用两个或多个一样的对象,如果使用 new 关键字重新创建对象,再赋值上相同的属性,这样做比较烦琐而且也容易出错。PHP 提供了对象克隆功能,可以根据一个对象完全克隆出一个一模一样的对象,而且克隆以后,两个对象互不干扰。
使用关键字 clone 来克隆对象。语法:
$object2 = clone $object;
例子:
<?php
class Person {private $name;private $age;function __construct($name, $age) {$this->name=$name;$this->age=$age;}function say() {echo "我的名字叫:".$this->name."<br />";echo "我的年龄是:".$this->age;}
}$p1 = new Person("张三", 20);
$p2 = clone $p1;
$p2->say();
?>
运行例子,输出:
我的名字叫:张三
我的年龄是:20
__clone()
如果想在克隆后改变原对象的内容,需要在类中添加一个特殊的 __clone() 方法来重写原本的属性和方法。__clone() 方法只会在对象被克隆的时候自动调用。
例子:
<?php
class Person {private $name;private $age;function __construct($name, $age) {$this->name = $name;$this->age = $age;}function say() {echo "我的名字叫:".$this->name;echo " 我的年龄是:".$this->age."<br />";}function __clone() {$this->name = "我是假的".$this->name;$this->age = 30;}
}$p1 = new Person("张三", 20);
$p1->say();
$p2 = clone $p1;
$p2->say();
?>
运行例子,输出:
我的名字叫:张三 我的年龄是:20
我的名字叫:我是假的张三 我的年龄是:30
PHP对象赋值与克隆相关推荐
- 13接口登记案例 把对象赋值给接口
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- python怎样给对象赋值_Python对象赋值、浅拷贝和深拷贝
总结: 1.copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象 2.copy.deepcopy 深拷贝 拷贝对象及其子对象 1.对象赋值 will = ["Will&quo ...
- C风格字符串和C++ string 对象赋值操作的性能比较
<<C++ Primer>> 第四版 Exercise Section 4.3.1 部分Exercise 4.2.9 习题如下: 在自己本机执行如下程序,记录程序执行时间: 1 ...
- python类对象赋值_Python对象赋值、浅拷贝、深拷贝
Python中,基本数据类型,理解为常见数据类型:布尔型.整型.浮点型.字符串.列表.元组.字典.集合,随语言不同而不同,但是根据在内存中存储方式的不同,区分开原子类型和容器类型. 对象赋值 对象的赋 ...
- Java中ListE对象赋值问题(引用传递和值传递)
Java中List<E>对象赋值操作问题 业务需求是:取2个集合中的交集对象并返回.如下代码,busMap中key值和stocks中Map中的key值相等的对象则返回继续操作,也就是说剔除 ...
- python中可迭代对象拆包时、怎么赋值给占位符_python3-数据结构和算法 » 1.2 解压可迭代对象赋值给多个变量...
1.2 解压可迭代对象赋值给多个变量 问题 如果一个可迭代对象的元素个数超过变量个数时,会抛出一个 ValueError . 那么怎样才能从这个可迭代对象中解压出 N 个元素出来? 解决方案 Pyth ...
- [深入学习C#]利用反射给对象赋值
转载自诗人江湖老,原文地址 C#中利用反射能够获取对象的属性信息,也可以利用反射给对象赋值. 我们如果想利用凡是给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值,但 ...
- 基本类型赋值和普通对象赋值的不同
对象赋值是Reference(参考)赋值,而基本类型是直接值得拷贝. package qwer;public class asdf {public static void main(String[] ...
- 8-2:C++继承之父类和子类对象赋值转换(公有继承)也即切片
父类和子类对象赋值转换(公有继承) - - - 父类和子类对象赋值转换是指:子类对象可以赋值给父类对象(父类的指针或引用也可以),而父类对象不能赋值给子类对象.也就Student一定是Person,但 ...
最新文章
- form 表单 + HTML5(FileReader) +iframe 实现无刷新图片上传+图片预览效果
- dnf加物理攻击的卡片有哪些_DNF新版本完美附魔太贵,这些紫卡附魔也不错
- 专访腾讯徐汉彬:日请求高达3.5亿+平台的架构设计及演变
- java Poi导入exel表格的数据,入库
- Hadoop, Hbase
- JS魔法堂:那些困扰你的DOM集合类型
- 093-PHP数组比较
- javascript紧接上一张for循环的问题,我自己的理解
- 无法初始化Winsock2.2处理
- 文件共享服务器(CIFS协议)
- 汇编语言学习篇2——MASM的环境搭建(win10与Ubuntu1604下的配置)【有问题,待更正】
- 红黑树时间复杂度为什么是O(logn)?
- (萌新笔记)python的复习笔记
- 一个简单的BitTorrent客户端实现(五):tracker manager和tracker实现
- 3D影视建模:你这个糟老头子坏的很,来看看《糟老头子》制作流程分享
- 汉字从拼音到文字的完整映射表
- android type-c 接电视,有Type - C接口,却想电脑直连电视机?教你5个方法,简单又实用...
- Prolog教程 14--cut的功能
- H3C EPON技术白皮书
- 年报背后:顺丰疯狂的错位价格战