先看一段代码,想一下会输出什么
$arr = [1, 2, 3];
foreach ($arr as $k=>&$v) {
$v = $v * 2;
}
foreach($arr as $v) {
echo $v,"\n";
}
正确答案是:
2
4
4
如果跟预想的不一样,说明你还没有弄明白 foreach 循环的本质。
foreach 基础用法
$arr = [1, 2, 3, 4];
foreach ($arr as $k=>$v) {
// $v = $arr[$k];
}
在循环遍历数组元素时,每遍历一个数组元素,将当前指针对应的数组元素赋值给 $v
。
循环结束,$v
仍然存在,值等于最后一次遍历的数组元素(循环没有提前结束即为最后一个数组元素)
结合引用的用法
$arr = [1, 2, 3, 4];
foreach ($arr as $k=>&$v) {
// $v = &$arr[$k];
}
在循环遍历数组元素时,每遍历一个数组元素,将当前指针对应的数组元素引用赋值给 $v
。
循环结束,$v
仍然存在,$v
的地址空间引用的是最后一次遍历的数组元素(循环没有提前结束则为最后一个数组元素)
使用引用的影响
在循环体内修改
$v
的值,同时会修改数组对应元素的值$arr = [1, 2, 3];
foreach ($arr as $k=>&$v) {
$v = $v * 2;
}
//循环结束后,$arr = [2,4,6];
在循环结束后,修改
$v
的值,同时会修改最后一次遍历的数组元素$arr = [1, 2, 3];
foreach ($arr as $k=>&$v) {
$v = $v * 2;
}
//循环结束后,$arr = [2,4,6];
$v = 10;
//为$v赋值后,$arr = [2,4,10];
如果再次循环遍历数组,且使用相同的变量
$v
,则每遍历一个数组元素为$v
赋值时,均会修改前一遍遍历数组时最后一次遍历的数组元素$arr = [1, 2, 3];
foreach ($arr as $k=>&$v) {
$v = $v * 2;
}
foreach($arr as $k=>$v) {
echo $v,"\n";
//$k为0时,$arr变为[2,4,2]
//$k为1时,$arr变为[2,4,4]
//$k为2时,$arr为[2,4,4]
}
为了防止循环结束后,对 $v
赋值,或者再次循环遍历数组造成问题,可以在第一遍遍历结束后,及时使用 unset($v)
切断引用关系