一丶
<?php
$a=range[0,1000]; //$a在赋值时计算机会开辟一块内存地址
$b=$a; //$b等于$a时,由于php的copy on write机制,这时的$b和$a指向的是同一块内存地址,
xdebug_debug_zval('a') //要使用此函数需安装xdebug扩展,查看变量的引用情况为false,地址对应的变量数量为2
$a=range[1,1000]; //重新给$a赋值,即使和之前的值一样,这时php会重新开辟一块内存地址给$a,而$b的内存地址不变,
xdebug_debug_zval('a'); //此时变量的引用为false,地址对应的变量数为1,说明重新开辟了地址
如果将$b=$a改为$b=&$a,$b和$a指向了同一个地址,但是php的cow机制不会触发了,这时即使$a重新赋值,也始终指向原来的地址。
?>
二丶
<?php
$a = range[0,1000];
$b = &$a; //引用变量不会触发cow机制
unset($b); //此时的unset操作只会取消$b的引用,实际的变量地址此时仅有$a一个变量指向它
echo $a;
?>
三丶
<?php
//对象本身就是引用传递
class Person
{
public $name = "zhangsan";
}
$p1 = new Person;
xdebug_debug_zval('p1'); //指向该地址的变量共1个,引用传递为false
$p2 = $p1;
xdebug_debug_zval('p1'); //指向该地址的变量共2个,引用传递为false
$p2->name = "lisi"; //对p2重新赋值
xdebug_debug_zval('p1'); //指向该地址的变量共2个,引用传递为false
?>
对象和变量不同,对象没有cow机制,在重新赋值时不会重新开辟内存空间,他们是共用同一内存空间,所以在对p2进行修改时,p1也会被改为lisi,如果想要进行复制,可以使用clone克隆对象。
四丶
$data每一次循环的值是什么?
<?php
$data = ['a','b','c'];
foreach($data as $key=>$val)
{
$val = &$data[$key];
}
?>
第一次循环时,$key = 0,$val = a,进入循环体$val重新赋值为$data[0],此时$val和$data[$key]指向同一块地址,$val=a,$data =['a','b','c'] .
第二次循环,$key = 1,$val = b,进入循环体,$val重新赋值为$data[1],此时$val=b,$data[0]=b,$data=['b','b','c'].第三次循环时,$data = ['b','c','c'].
网友评论