如果没有安装xdebug,请先安装:
地址xdebug安装
先看如下代码:
<?php
$foo['world'] = '0';
$foo['hello'] = 'A';
xdebug_debug_zval('foo');
foreach($foo as &$value) { // 引用!
// Do nothing.
}
$tipi = $foo;
$tipi['hello'] = 'B';
$tipi['world'] = '1';
xdebug_debug_zval('foo');
print_r($foo);
输出结果:(为什么呢)
foo: (refcount=1, is_ref=0)=array ('world' => (refcount=0, is_ref=0)='0', 'hello' => (refcount=0, is_ref=0)='A')
foo: (refcount=1, is_ref=1)=array ('world' => (refcount=1, is_ref=1)='0', 'hello' => (refcount=3, is_ref=1)='B')
从这看可想而知
该结果输出的结果为
Array
(
[world] => 0
[hello] => B
)
那如果稍作改变:
<?php
$foo['world'] = '0';
$foo['hello'] = 'A';
xdebug_debug_zval('foo');
foreach($foo as &$value) { // 引用!
// Do nothing.
}
unset($value);
$tipi = $foo;
$tipi['hello'] = 'B';
$tipi['world'] = '1';
xdebug_debug_zval('foo');
print_r($foo);
输出结果为:
foo: (refcount=1, is_ref=0)=array ('world' => (refcount=0, is_ref=0)='0', 'hello' => (refcount=0, is_ref=0)='A')
foo: (refcount=1, is_ref=1)=array ('world' => (refcount=1, is_ref=1)='0', 'hello' => (refcount=1, is_ref=1)='A')
Array
(
[world] => 0
[hello] => A
)
具体分析一下:
因为foreach里面是引用,而循环之后,value并没有销毁(PHP 在控制结构后不会回收变量)
所以这里就造成了变量污染,把最后一个变量给污染了,该例子中hello是在最后面,所以hello就被污染成下面的值。
所以在开发中,请保持及时unset的好习惯!
延申:
<?php
$arr = [1,2];
foreach ($arr as &$val) {
echo $val . PHP_EOL;
}
foreach ($arr as $val) {
echo $val . PHP_EOL;
}
这个输出什么呢?
结果为:
1
2
1
1
那么根据上面的分析,第一个foreach肯定是输出1,2
那么第二个的时候$arr = [1,2];
而最后一个变量已经被污染了,所以2会被该变量的第一个替换,所以就变成[1,1]
那么自然就是输出1,1