PHP foreach ($arr as &$value)
foreach ($arr as &$value)
看到一个有意思的东西:
<?php $arr = ['1', '2', '3', '4']; foreach ($arr as &$i) {} echo implode($arr, ', ')."\n"; foreach ($arr as $i) {} echo implode($arr, ', ')."\n"; ?>
运行结果:
1, 2, 3, 4 1, 2, 3, 3
当使用了 & 引用后,下一次遍历数组的结果发生了变化
调试下看看:
$arr = ['1', '2', '3', '4']; foreach ($arr as &$i) {} echo implode($arr, ', ')."\n"; var_dump($arr);
for($i=0;$i<count($arr);$i++){ echo $arr[$i]."-$i, "; var_dump($arr); } echo "\n"; foreach ($arr as $i) {} echo implode($arr, ', ')."\n";
运行结果(可以看到,第二次循环里面,每次循环后,最后一个数组元素一直被引用着,而且等于当时数组遍历的值):
1, 2, 3, 4 array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> &string(1) "4" } 1-0, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> &int(0) } 2-1, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> &int(1) } 3-2, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> &int(2) } 3-3, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> &int(3) } 1, 2, 3, 3
因为使用了 & 后,会影响后面的赋值,可以使用 unset 销毁变量
验证一下:
$arr = ['1', '2', '3', '4']; foreach ($arr as &$i) {} echo implode($arr, ', ')."\n"; var_dump($arr); unset($i); for($i=0;$i<count($arr);$i++){ echo $arr[$i]."-$i, "; var_dump($arr); } echo "\n"; foreach ($arr as $i) {} echo implode($arr, ', ')."\n";
输出:
1, 2, 3, 4 array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> &string(1) "4" } 1-0, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" } 2-1, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" } 3-2, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" } 4-3, array(4) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" [3]=> string(1) "4" } 1, 2, 3, 4
分析:
第一个 foreach 循环完以后,$i 指向 $arr[3],在第二个 foreach 循环时,这个引用没有断开
第二个 foreach 循环中:
第一次循环:$i = $arr[0] ;而 $i 又是 $arr[3] 的引用,则 $i 等于 $arr[3] 等于 $arr[0] 等于 '1' ,即 $i = $arr[3] = '1'
第二次循环:$i = $arr[1] ;而 $i 又是 $arr[3] 的引用,则 $i 等于 $arr[3] 等于 $arr[1] 等于 '2' ,即 $i = $arr[3] = '2'
第三次循环:$i = $arr[2] ;而 $i 又是 $arr[3] 的引用,则 $i 等于 $arr[3] 等于 $arr[2] 等于 '3' ,即 $i = $arr[3] = '3'
第四次循环:$i = $arr[3] = 3;
第四次循环:$i = $arr[3] = 3;