在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对象赋值与克隆相关推荐

  1. 13接口登记案例 把对象赋值给接口

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. python怎样给对象赋值_Python对象赋值、浅拷贝和深拷贝

    总结: 1.copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象 2.copy.deepcopy 深拷贝 拷贝对象及其子对象 1.对象赋值 will = ["Will&quo ...

  3. C风格字符串和C++ string 对象赋值操作的性能比较

    <<C++ Primer>> 第四版 Exercise Section 4.3.1 部分Exercise 4.2.9 习题如下: 在自己本机执行如下程序,记录程序执行时间: 1 ...

  4. python类对象赋值_Python对象赋值、浅拷贝、深拷贝

    Python中,基本数据类型,理解为常见数据类型:布尔型.整型.浮点型.字符串.列表.元组.字典.集合,随语言不同而不同,但是根据在内存中存储方式的不同,区分开原子类型和容器类型. 对象赋值 对象的赋 ...

  5. Java中ListE对象赋值问题(引用传递和值传递)

    Java中List<E>对象赋值操作问题 业务需求是:取2个集合中的交集对象并返回.如下代码,busMap中key值和stocks中Map中的key值相等的对象则返回继续操作,也就是说剔除 ...

  6. python中可迭代对象拆包时、怎么赋值给占位符_python3-数据结构和算法 » 1.2 解压可迭代对象赋值给多个变量...

    1.2 解压可迭代对象赋值给多个变量 问题 如果一个可迭代对象的元素个数超过变量个数时,会抛出一个 ValueError . 那么怎样才能从这个可迭代对象中解压出 N 个元素出来? 解决方案 Pyth ...

  7. [深入学习C#]利用反射给对象赋值

    转载自诗人江湖老,原文地址 C#中利用反射能够获取对象的属性信息,也可以利用反射给对象赋值. 我们如果想利用凡是给一个对象属性赋值可以通过PropertyInfo.SetValue()方式进行赋值,但 ...

  8. 基本类型赋值和普通对象赋值的不同

    对象赋值是Reference(参考)赋值,而基本类型是直接值得拷贝. package qwer;public class asdf {public static void main(String[] ...

  9. 8-2:C++继承之父类和子类对象赋值转换(公有继承)也即切片

    父类和子类对象赋值转换(公有继承) - - - 父类和子类对象赋值转换是指:子类对象可以赋值给父类对象(父类的指针或引用也可以),而父类对象不能赋值给子类对象.也就Student一定是Person,但 ...

最新文章

  1. form 表单 + HTML5(FileReader) +iframe 实现无刷新图片上传+图片预览效果
  2. dnf加物理攻击的卡片有哪些_DNF新版本完美附魔太贵,这些紫卡附魔也不错
  3. 专访腾讯徐汉彬:日请求高达3.5亿+平台的架构设计及演变
  4. java Poi导入exel表格的数据,入库
  5. Hadoop, Hbase
  6. JS魔法堂:那些困扰你的DOM集合类型
  7. 093-PHP数组比较
  8. javascript紧接上一张for循环的问题,我自己的理解
  9. 无法初始化Winsock2.2处理
  10. 文件共享服务器(CIFS协议)
  11. 汇编语言学习篇2——MASM的环境搭建(win10与Ubuntu1604下的配置)【有问题,待更正】
  12. 红黑树时间复杂度为什么是O(logn)?
  13. (萌新笔记)python的复习笔记
  14. 一个简单的BitTorrent客户端实现(五):tracker manager和tracker实现
  15. 3D影视建模:你这个糟老头子坏的很,来看看《糟老头子》制作流程分享
  16. 汉字从拼音到文字的完整映射表
  17. android type-c 接电视,有Type - C接口,却想电脑直连电视机?教你5个方法,简单又实用...
  18. Prolog教程 14--cut的功能
  19. H3C EPON技术白皮书
  20. 年报背后:顺丰疯狂的错位价格战

热门文章

  1. 实在智能RPA助你揭开淘宝搜索权重引流规则
  2. 大一 JAVAOOP-T2 面向 对象 进阶- 实践任务指南(美和易思)
  3. Python计算机二级编程题真题及考点总结(上篇)
  4. HUAWEI HiAI常见FAQ小贴士
  5. Radio Link Failure and Recovery
  6. 机器学习的基本数学知识1
  7. 论背景调查,《长安十二时辰》的大案牍术可比不上现在
  8. Openpbs centos7集群安装配置心得
  9. webrtc性能优化:MacOS下的快速截屏录屏方式
  10. Intermec PX4I 高性能条码打印机 助力信息化