4 回答
![?](http://img1.sycdn.imooc.com/545861b80001d27c02200220-100-100.jpg)
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_ref
和refcount
在普通变量赋值和引用赋值时候的一些改变情况:
$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');
相信你会有所发现,以上。
![?](http://img1.sycdn.imooc.com/5333a01a0001ee5302000200-100-100.jpg)
TA贡献1829条经验 获得超4个赞
这就是普通赋值和引用赋值的区别,普通赋值只是把$a的值传递给了$b,而下面的引用赋值不仅把$b指向了和$a相同的地址空间,这个时候$b就是$a,即使现在unset($b),输出的时候还是会输出并且他的值是$a.
![?](http://img1.sycdn.imooc.com/533e50ed0001cc5b02000200-100-100.jpg)
TA贡献1858条经验 获得超8个赞
上面都很平常
下面这段,&$a,意思是让a都使用同一个地址
$a = null;给这个地址赋值为null,所以打印的就是null
应该是这样,恩没错就是这样~~~~
![?](http://img1.sycdn.imooc.com/5333a207000118af02200220-100-100.jpg)
TA贡献2021条经验 获得超8个赞
第一个是按值传递,传递的是对象的内存地址,$a和$b的值都指向了对象的内存地址
第二个是引用传递,传递的是变量的地址。通过学习c/c++语言,我们知道,变量本身需要有一个空间存放自己的地址,而$b的值指向了$a的内存地址,所以第二个unset($a)会把变量分配的内存给销毁,而$b是通过$a的地址去找对象的内存地址的,没了$a,$b自然是指向了无效的内存地址。
- 4 回答
- 0 关注
- 527 浏览
添加回答
举报