关于foreach的一个小问题
今天在群里有网友说了这样一个问题:
$data = array('a', 'b', 'c');
foreach($data as $key=>$val) { $val = &$data[$key]; //unset($val); }
$var_dump($data);
问$var_dump($data)的结果是什么,为什么?
运行后结果是:
$data: array(3) { [0]=> string(1) "b" [1]=> string(1) "c" [2]=> &string(1) "c" }
why?
于是重新修改下代码并且在循环的时候打印出结果来查看,代码如下:
foreach($data as $key=>$val) { echo '<br/>第'.($key+1).'次循环</br>'; var_dump($data); echo '$val is:'.$val.'</br>'; $val = &$data[$key]; //unset($val);//这里unset后就不会出现问题。 var_dump($data); }
结果如下:
第1次循环
array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" } $val is:a
array(3) { [0]=> &string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" }
第2次循环
array(3) { [0]=> &string(1) "b" [1]=> string(1) "b" [2]=> string(1) "c" } $val is:b
array(3) { [0]=> string(1) "b" [1]=> &string(1) "b" [2]=> string(1) "c" }
第3次循环
array(3) { [0]=> string(1) "b" [1]=> &string(1) "c" [2]=> string(1) "c" } $val is:c
array(3) { [0]=> string(1) "b" [1]=> string(1) "c" [2]=> &string(1) "c" }
分析后觉得原因在这里:
$key=0时,$val = &$data[0]; 表示$val引用的是$data的第0项,
$key=1时,遍历时使$val="b"; 而根据上面知道$val引用了$data[0],于是使$data[0]="b"; 然后$val = &$data[1];
$key=2时,遍历时使$val="c"; 而根据上面知道$val引用了$data[1],于是使$data[1]="c";
所以得到上面的结果。
以上为个人理解,不知是否正确。
还有一个例子:
$arr=array(1,3,5); foreach($arr as &$v) { $v+=1; } foreach($arr as $k=> $v) { //echo "<br/>"; echo $v; //$v+=1; //echo "<br/>"; var_Dump($arr); //echo "<br/>"; } 输出结果为:2 4 4 原因:$v在第1个foreach结束后,指向$arr的最后一次元素(即$arr[2])的引用。在下面任然有效。 在第2个foreach中第1次和第2次循环分别使$arr[2]=2、$arr[2]=4; 2 array(3) { [0]=> int(2) [1]=> int(4) [2]=> ∫(2) } 4 array(3) { [0]=> int(2) [1]=> int(4) [2]=> ∫(4) } 4 array(3) { [0]=> int(2) [1]=> int(4) [2]=> ∫(4) }
解决办法:在第一个foreach循环完后unset($v)