已知数组:
$arr = ['a','b','c'];
在没有对数组进行 &地址引用的情况下,foreach循环两次后$arr数组的值是不会改变,这点毋庸置疑。
foreach ($arr as $v){}
foreach ($arr as $v){}
案例1: 首次循环加一个&取地址遍历,不unset
echo "第1次循环\n";
foreach ($arr as &$v){
echo "{$v}\n";
}
echo "第2次循环\n";
foreach ($arr as $v){
echo "{$v}\n";
}
print_r($arr);
// 输出
第1次循环
a
b
c
第2次循环
a
b
b
$arr 最后的值为:
Array
(
[0] => a
[1] => b
[2] => b
)
案例2:首次循环加一个&取地址遍历,加一个unset($v)
echo "第1次循环\n";
foreach ($arr as &$v){
echo "{$v}\n";
}
unset($v);
echo "第2次循环\n";
foreach ($arr as $v){
echo "{$v}\n";
}
print_r($arr);
// 输出又变正常了,
第1次循环
a
b
c
第2次循环
a
b
c
$arr 最后的值为:
Array
(
[0] => a
[1] => b
[2] => c
)
原因分析:
取官方手册里说明:
回到案例1中, a r r 数组,第一次 f o r e a c h 循环结束后 , arr 数组,第一次foreach循环结束后, arr数组,第一次foreach循环结束后,v指向的是$arr中的最后一个元素,也就是 a r r [ 2 ] ;在第二次循环时候,每次 arr[2]; 在第二次循环时候,每次 arr[2];在第二次循环时候,每次v的值也是赋值给$arr[2]改变其中的值,把值的变动过程打印出来:
$arr = ['a','b','c'];
echo "第1次循环\n";
foreach ($arr as &$v){
echo "{$v}\n";
}
//unset($v);
echo "第2次循环\n";
foreach ($arr as $v){
echo "{$v}\n";
print_r($arr);
}
// 输出:
第1次循环
a
b
c
第2次循环
a
Array
(
[0] => a
[1] => b
[2] => a
)
b
Array
(
[0] => a
[1] => b
[2] => b
)
b
Array
(
[0] => a
[1] => b
[2] => b
)
第一次遍历, 将 arr[0] 赋值给 $v, 相当于 arr[2]=arr[0], 此时 arr 为: [‘a’, ‘b’, ‘a’]
第二次遍历, 将 arr[1] 赋值给 $v, 相当于 arr[2]=arr[1], 此时 arr 为: [‘a’, ‘b’, ‘b’]
第三次遍历, 将 arr[2] 赋值给 $v, 相当于 arr[2]=arr[2], 此时 arr 为: [‘a’, ‘b’, ‘b’]
所以遍历出异常了,保险起见,foreach循环的$v最好都unset掉。