为了账号安全,请及时绑定邮箱和手机立即绑定

这两种方式赋值的结果为什么不一样呢?

这两种方式赋值的结果为什么不一样呢?

PHP
万千封印 2019-03-13 19:54:19
查看完整描述

4 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

先清楚一个概念:

普通赋值,改变一个,其余变量值不变;
引用变量赋值,改变一个,其余变量值跟着变;

再来细说:
其实这种情况都和引用计数有关。

我们知道在php中存储变量的是一个叫做zval的容器,这个容器中除了存放数据值和类型之外,还存放了两个信息,一个是is_ref,表示这个变量是否是引用变量,另外一个是refcount,表示的是变量的个数;接下来看代码:

看你第一种

$a = new Per();
$b = $a;
$a = null;

第二行,把已经赋值过的变量a再赋值给b的时候,这个时候是普通变量之间的互相赋值。所以is_ref这个标识不会改变,而refcount则会自增+1;因为$a 和 $b 的值和数据类型都是相同的,所以用同一个zval容器也没问题;

但是下面的时候,把其中一个的值修改了,那么原先$a上的refcount就会自减一;而$b就会使用一个新的内存地址,生成一个新的zval容器。

看第二种:

$a = new Per();
$b = &$a;
$a = null;

这种情况下,看第二行,当有引用动作的时候,$a变量里的is_ref标识则会从0变为1,表示这个变量是引用变量;而refcount则会自增+1,表示容器的变量个数;

由于使用的是同一内存地址,同一zval容器,又是引用关系。所以改一个值,其余的引用的值,都会跟着改变了。

可以用下面代码测试,is_refrefcount在普通变量赋值和引用赋值时候的一些改变情况:

$a = 10;
xdebug_debug_zval('a');
$b = &$a;
xdebug_debug_zval('a');
$a = 20;
xdebug_debug_zval('a');



$a = 10;
xdebug_debug_zval('a');
$b = $a;
xdebug_debug_zval('a');
$a = 20;
xdebug_debug_zval('b');

相信你会有所发现,以上。

查看完整回答
反对 回复 2019-03-18
?
浮云间

TA贡献1829条经验 获得超4个赞

这就是普通赋值和引用赋值的区别,普通赋值只是把$a的值传递给了$b,而下面的引用赋值不仅把$b指向了和$a相同的地址空间,这个时候$b就是$a,即使现在unset($b),输出的时候还是会输出并且他的值是$a.

查看完整回答
反对 回复 2019-03-18
?
猛跑小猪

TA贡献1858条经验 获得超8个赞

上面都很平常
下面这段,&$a,意思是让a都使用同一个地址
$a = null;给这个地址赋值为null,所以打印的就是null
应该是这样,恩没错就是这样~~~~

查看完整回答
反对 回复 2019-03-18
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

第一个是按值传递,传递的是对象的内存地址,$a和$b的值都指向了对象的内存地址

第二个是引用传递,传递的是变量的地址。通过学习c/c++语言,我们知道,变量本身需要有一个空间存放自己的地址,而$b的值指向了$a的内存地址,所以第二个unset($a)会把变量分配的内存给销毁,而$b是通过$a的地址去找对象的内存地址的,没了$a,$b自然是指向了无效的内存地址。

查看完整回答
反对 回复 2019-03-18
  • 4 回答
  • 0 关注
  • 527 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信