上一篇我们讲了变量赋值的问题。其中一个问题是对象在给变量赋值的时候,是直接通过引用赋值的。那么真实情况是怎样的呢?在之前的变量赋值文章中,PHP变量赋值对象参考测试。继续深入研究PHP手册后,发现原来的对象确实不是直接引用的拷贝。使用手册中的以下例子来分析:$实例=空;//$instance和$reference变为空var_dump($instance);var_dump($reference);var_dump($assigned);$instance是实例化后的SimpleClass对象$assigned直接赋值$reference先引用赋值,我们为$instance对象定义一个变量var,然后将$instance赋值为null。作为参考,$reference变量自然变为null但$assigned不会变为null。还是SimpleClass的一个实例对象,而且,关键点:它有var属性是不是很神奇?从逻辑上讲,普通赋值就是一个副本,两个变量不会互相影响。引用赋值就是复制指针(同一个内存地址),修改任何一个变量,其他变量也会改变。但是对象的普通分配似乎不属于它们中的任何一个。$reference很好理解,用&符号赋值,说明这个变量是引用赋值。它成为$instance的快捷方式,它会随着$instance的所有变化而变化。这是在变量级别。$assigned实际上是代码中的普通赋值。但是,对象是一种特殊的形式,普通赋值赋值的值实际上是对象的一个??句柄。PHP手册中有一个Note是这样描述的:首先,将PHP中的变量一一当作数据槽。这个数据槽可以容纳原始类型(int、string、bool等)。创建引用时,内存地址存储在这个槽中,或者是指向被引用对象的指针。引用没有复制操作,只是指向原始变量(引用数据结构)的指针。创建普通赋值时,复制的是基类型。对象不同于基本类型,它不能直接存放在数据槽中,而是将对象的“句柄”存放在数据槽中。此句柄是指向对象的特定实例的标识符。手柄虽然不是我们可以直观操作的类型,但也是一种基本类型。当您获取一个包含对象句柄的变量并将其分配给另一个变量时,另一个变量将获得该对象的句柄。(注意,不是引用!不是引用!不是引用!!)。通过句柄,两个变量可以修改同一个对象。然而,这两个变量并不直接相关。它们是两个自变量。当一个变量更改为另一个值时,不会影响另一个变量。只有当变量修改了对象内部的内容时,另一个变量持有相同的句柄,所以它的对象内容才会相应改变。注意原文:https://www.php.net/manual/zh/language.oop5.basic.php#79856总结通过本文的分析,我们可以看出,变量赋值只是一种变量级别的操作。它总是只保存一个值。正常分配时,该值是原始类型。通过引用分配时,存储的原始类型是指针。无论如何,它不会直接将普通赋值转换为引用赋值,因为它保存的是一个对象,真正的引用赋值必须加上一个&符号。这个内容有点绕,但是这样的内容更能体现一个人的核心竞争力。看一百遍的意义不言而喻,手册中的很多知识我都要来回学习才能理解。上面的笔记作者写的很好,英文好的朋友可以直接看英文原版。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/201911/source/%E5%AF%B9%E8%B1%A1%E8%B5%8B%E5%80%BC%E5%9C%A8PHP%E4%B8%AD%E5%88%B0%E5%BA%95%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BC%95%E7%94%A8%EF%BC%9F.php参考文档:https://www.php.net/manual/zh/language.oop5.basic.php所有媒体平台均可搜索【硬核项目经理】
