PHP中关于foreach使用引用变量的坑
PHP版本为 5.6.12 代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php $arr = [ 'a' , 'b' , 'c' , 'd' , 'e' ]; foreach ( $arr as $i =>& $a ) { $a = $a . '_' . $a ; echo $a . '<br>' ; } echo '<hr>' ; foreach ( $arr as $i => $a ) { echo $a . '<br>' ; } echo '<hr>' ; print_r( $arr ); |
输出结果
一开始看到第二个 foreach 输出的结果感觉很是莫名其妙,怎么会输出两个 d_d 呢?
仔细想了想,原来因为PHP foreach 中的 $a 的作用域是整个函数的局部变量,在循环外部仍然有效,而不是被封闭在循环内的,
所以当执行第二个foreach 时的 $a 并不是新的变量,而是仍然指向 $arr 数组第5个元素的地址引用,
当第二个 foreach 在循环时实际上是在不停的给 $arr 数组的第5个元素赋值,
具体赋值情况,
第一次:a_a 赋值给第5个元素, 结果为: [a_a, b_b, c_c, d_d,a_a]
第二次:b_b 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,b_b]
第三次:c_c 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,c_c]
第四次:d_d 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,d_d]
第五次:此时因为第五个元素已经变成 d_d 又重新把 d_d 赋值给第5个元素,结果还是为: [a_a, b_b, c_c, d_d,d_d]
解决办法:
1.尽量不使用相同的循环变量名;
2.每次使用完或再次使用前进行 unset($a); 处理,解除地址应用
foreach
(
$arr
as
$i
=>&
$a
) {
$a
=
$a
.
'_'
.
$a
;
echo
$a
.
'<br>'
;
}
echo
'<hr>'
;
echo
$a
;
echo
'<hr>'
;
// 这里 unset 掉
unset(
$a
);
echo
$a
=
'ccc'
;
echo
'<hr>'
;
print_r(
$arr
);
echo
'<hr>'
;
foreach
(
$arr
as
$i
=>
$a
) {
echo
$a
.
'<br>'
;
}
echo
'<hr>'
;
print_r(
$arr
);
输出结果:
现在就正常了