class php 用变量赋值 类_PHP变量 之 对象类型变量

在 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 所指向的那个对象。新创建的对象在函数执行之后被销毁。

所以有代码中注释的输出结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值