先看代码
$arr = [1, 2, 3]; | |
foreach($arr as &$value){ | |
} | |
foreach($arr as $value){ | |
} | |
print_r($arr); | |
// 预期 | |
Array | |
( | |
[1 | ] =>|
[2 | ] =>|
[3 | ] =>|
) | |
// 实际 | |
Array | |
( | |
[1 | ] =>|
[2 | ] =>|
[2 | ] =>|
) |
foreach 在执行的时候,会依次把数组 $arr 键的值赋值给 $value,并且 $value 并不是局部变量,它存在于全局中。
所以在第二次 foreach 执行的时候,此时的 $value = &$arr[2],由于它的内存地址指向了 $arr[2],所以在第二次的 foreach 循环中,每一次对 $value 的赋值,其实都是在改变 $arr[2] 的值。
$arr = [1, 2, 3]; | |
foreach($arr as &$value){ | |
// 第一次循环 $value = &$arr[0]; | |
// 第二次循环 $value = &$arr[1]; | |
// 第三次循环 $value = &$arr[2]; | |
} | |
// 循环结束后由于 $value 处于全局中,它依然指向 $arr[2] | |
// 于是: | |
foreach($arr as $value){ | |
// 第一次循环 $value = $arr[0]; | |
// 实际上 $arr[2] = $arr[0]; | |
// 第二次循环 $value = $arr[1]; | |
// 实际上 $arr[2] = $arr[1]; | |
// 第三次循环 $value = $arr[2]; | |
// 实际上 $arr[2] = $arr[2]; | |
// 此时 $arr[2] 与 $arr[1] 相等 | |
} |
要解决这个问题也很简单
$arr = [1, 2, 3]; | |
foreach($arr as &$value){ | |
} | |
// 每次循环引用数组值的时候,循环之后要将 $value 释放掉 | |
unset($value); | |
foreach($arr as $value){ | |
} | |
print_r($arr); | |
// 输出 | |
Array | |
( | |
[0] => 1 | |
[1] => 2 | |
[2] => 3 | |
) |
这应该是 PHP 新手 经常忽略的问题,要记住 foreach 并不像 function 一样产生作用域,他的变量处在全局中。
记录一下。