近期使用php开发过程中,发现一个foreach中 引用的小坑。
1.现象
如下代码:
$arr = [1, 2, 4];
foreach ($arr as &$a) {
$a = $a * $a;
}
print_r($arr);
foreach($arr as $a){
print_r($a);
print(" ");
}
打印结果:
Array
(
[0] => 1
[1] => 4
[2] => 16
)
1 4 4
2.原因
为什么在第一次遍历中使用引用后,第二次遍历最后一个元素结果异常?
问题解释官方参考中可以知道foreach“引用”后,数组中最后一个元素的引用仍会保留,需要手动删除,即应在第一次遍历后添加unset($a);
3.分析
打印如下:
$arr = [1, 2, 4];
foreach ($arr as &$a) {
$a = $a * $a;
}
print_r($arr);
foreach($arr as $k=>$a){
printf("----------------\n%d => %s\n", $k, $a);
print_r($arr);
}
打印结果:
Array
(
[0] => 1
[1] => 4
[2] => 16
)
------------
0 => 1
Array
(
[0] => 1
[1] => 4
[2] => 1
)
------------
1 => 4
Array
(
[0] => 1
[1] => 4
[2] => 4
)
------------
2 => 4
Array
(
[0] => 1
[1] => 4
[2] => 4
)
由上可以理解,在第一次遍历foreach中使用引用后,$a仍然是数组的末尾元素的引用。第二次遍历foreach时,相当于一直在对末尾元素做“赋值”覆盖操作;当执行到最后一步时,末尾元素自己对自己覆盖,原本的值来源于上一次覆盖,即倒数第二个元素的值,所以最后一个元素输出异常。
参考文章:PHP foreach使用 &引用 的坑