摘要:若一个变量是一个对象,那么该变量保存的就是一个引用类型的值,即变量中实际保存的是堆内存中对象的地址,而不是对象的实体若变量为其他类型,则保存的是基本类型值,而不是引用地址。新创建的对象在函数执行之后被销毁。
在 PHP 和 JavaScript 中(或许还有其他语言),变量内所保存的值分为 基本类型值 和 引用类型值。
$obj = new stdClass;
若一个变量是一个对象,那么该变量保存的就是一个引用类型的值,即变量中实际保存的是堆内存中对象的地址,而不是对象的实体;若变量为其他类型,则保存的是基本类型值,而不是引用地址。这一点需要特别注意,因为我们可能会遇到如下几种情况,不清楚原理可能导致出错。
赋值$obj_1 = new stdClass; $obj_2 = $obj_1; $obj_1->name = "Xavier"; var_dump($obj_1->name, $obj_2->name); var_dump($obj_1, $obj_2);
输出:
string(6) "Xavier" string(6) "Xavier" object(stdClass)#1 (1) { ["name"]=> string(6) "Xavier" } object(stdClass)#1 (1) { ["name"]=> string(6) "Xavier" }
我们发现 obj_2 的 name 也发生的改变,原因是 obj_1 和 obj_2 指向同一个对象 #1 ,因为在第二行中,我们将 obj_1 所指向的对象的地址赋给了 obj_2 。
传递参数我们来看这段代码:
function setName($obj) { $obj->name = "Xavier"; } $person = new stdClass; setName($person); var_dump($person->name); // 输出 string(6) "Xavier"
若变量为一个对象,那么当它作为参数传递给一个函数时,同样,传递的是一个对象地址,而不是拷贝了一个新的对象实体给参数 $obj 。这样,函数内部并没有 return 新的东西出来但改变了外部的状态 的这种情况就变得好理解了。
接下来,请看这段代码:
function setName($obj) { $obj->name = "Xavier"; $obj = new stdClass; $obj->name = "Zhao"; } $person = new stdClass; setName($person); var_dump($person->name); // 输出了 string(6) "Xavier" 而不是 string(6) "Zhao"
最后的输出结果可能会让很多人会疑惑,他们的思维可能是这样的:
我将 person 对象的引用地址传递给 obj参数
在函数内部第一行,根据 obj 的引用地址,我将函数外部对象的 name 属性设置成了 "Xavier"
在第二行,我将一个新的对象赋给了 obj ,既然 obj 为函数外部对象的引用,那么外部对象也一定变为了这个新的对象
然后我再给这个新的对象设置新的 name 属性 "zhao" ,嗯,这样外部对象的 name 一定也变成了 "zhao"
如果你想的和上方相同,那可就大错特错了,原因在于对传递参数的过程的错误理解。
首先,我们应该明白,将一个变量作为参数传递给函数 可以理解为 将那个变量保存的值 复制一份给 函数的参数(参数即函数范围的局部变量) 。当函数执行时,外部变量 和 函数参数(局部变量) 是同时存在于内存中的,并且两者是相互独立的,虽然两者所保存的值是相同的;函数参数(局部变量) 会在函数执行完毕后被销毁。
明白了上述原理,那么我们重新来看那段代码:
函数的 obj 变量在函数内第一行保存的是函数外部 person 变量所保存的值,也就是外部对象的地址
但到了第二行,obj 变量所保存的值变成了新创建的对象的地址,obj 的指向发生了改变,而原来的外部对象依旧存在并且只被 person 一个变量引用,所以在第三行的行为并没有影响到 person 所指向的那个对象。新创建的对象在函数执行之后被销毁。
所以有代码中注释的输出结果。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/28668.html
摘要:对于来说,变量有全局变量和局部变量之分那么,他们都是存储到一个哈希表内了么其实不是的,变量存储也有作用域的概念。 上次跟大家讲了垃圾回收机制后,有些小伙伴对底层原理比较感兴趣,私信问我了一些关于变量的相关知识,既然大家对变量比较感兴趣,那么这次我们来系统的讲一下变量的底层原理 变量结构 首先,我们还是先摆上我们的zval结构体,即php所有变量都会以zval结构体的形式实现 struc...
摘要:小驼峰法大驼峰法匈牙利命名法变量名属性类型对象描述。是一种弱类型语言,变量在使用之前并不需要声明类型,且同一变量可以保存多种不同类型的数据。另外,在函数内部创建的静态变量是无法在函数外部使用的。 变量标识符 标识符即是变量的名称,PHP 中关于变量的标识符有以下规则: 由任意字母、数字、下划线组成,但不能以数字开头 严格区分大小写 为了科学规范标识符,主要有以下几种流行的命名方式:...
摘要:若一个变量是一个对象,那么该变量保存的就是一个引用类型的值,即变量中实际保存的是堆内存中对象的地址,而不是对象的实体若变量为其他类型,则保存的是基本类型值,而不是引用地址。新创建的对象在函数执行之后被销毁。 在 PHP 和 JavaScript 中(或许还有其他语言),变量内所保存的值分为 基本类型值 和 引用类型值。 $obj = new stdClass; 若一个变量是一个对象,那...
摘要:面试专栏正式起更,每周一三五更新,提供最好最优质的面试内容。继上一篇面试常考内容之面向对象发表后,今天更新面向对象的最后一篇。面向对象的主要特征为封装继承多态。为了提高内聚性减少引起变化,单一原则是低耦合高内聚的面向原则上的引申。 PHP面试专栏正式起更,每周一、三、五更新,提供最好最优质的PHP面试内容。继上一篇PHP面试常考内容之面向对象(2)发表后,今天更新面向对象的最后一篇(3...
摘要:本文适合阅读用户有其他语言基础的童鞋看完语法教程来回顾一下的童鞋传送门,想全面看一下语法推荐这里毫无基础然而天资聪慧颇有慧根不要左顾右看说的就是你,老夫这里有一本从入门到放弃,观你根骨清奇两银子卖给你如何看完本文后你会收获到什么的变量的定义 本文适合阅读用户 有其他语言基础的童鞋 看完w3cschool语法教程来回顾一下的童鞋(传送门,想全面看一下php语法推荐这里) 毫无基础然而天...
阅读 702·2023-04-25 17:54
阅读 2944·2021-11-18 10:02
阅读 1115·2021-09-28 09:35
阅读 625·2021-09-22 15:18
阅读 2820·2021-09-03 10:49
阅读 2995·2021-08-10 09:42
阅读 2546·2019-08-29 16:24
阅读 1235·2019-08-29 15:08