foreach引用坑

先看下面代码

$arr1 = [1, 2];

foreach($arr1 as $key => $value) {
  $value = $value + 1;
}

var_dump($key, $value); //结果输出1,3

说明:在上面的foreach循环中,当循环结束后,临时变量 $key和$value变量都不会被自动释放掉。值会被保存下来。而且此时修改$val的值不会影响$arr。

理解foreach的原理,对上面的结果不难理解,foreach循环时,每次循环就会把`$arr1`元素的值复制给临时变量:$key, $value。如,第一次循环时,如下

$key = 0;
$value = $arr1[0];

第二次循环时,如下

$key = 1;
$value = $arr1[1];

 

再看forach中使用引用

引用:如果想在遍历数组的过程中修改数组的元素,可以在foreach中对$val使用引用。此时被引用的元素$val指向当前数组元素的内存地址,即共享一段内存地址。因此修改$val的值会同时改变$arr[$key]的值。

$arr1 = [1, 2];
foreach($arr1 as $key => $value) {
    $value = $value + 1;
}
var_dump($key, $value); //结果输出1,3

var_dump($arr1);
$arr1 的值 为 ['0' => 2, '1' => 3]

说明:$key , $value 的值和上面的非引用情况下一样。在foreach中使用&引用后,当foreach结束后,$key和$val变量也都不会被自动释放掉,但是此时$val和$arrcount($arr) - 1指向相同的内存地址。因此,此时修改$val的值也会改变了$arr[3]的值。

foreach 引用时,原理和上面一样,只不过是引用复制,原来如下

第一次循环:
$key = 0;
$value =  &$arr1[0];

第二次循环:
$key = 1;
$value =  &$arr1[1];

 

再看个例子:

$arr1 = [1, 2];
foreach($arr1 as $key => &$value) {
    $value = $value + 1;
}
var_dump($arr1);

$value = 100;

var_dump($arr1);

第二次输出 $arr1时,第二个元素的值也是100了。

理解了原理,就知道坑了。如果我们2个foreach循环,使用相同的临时变量就会有问题了,一个foreach在使用引用的时候。

如:

$arr1 = [1, 2];
foreach($arr1 as $key => &$value) {
    $value = $value + 1;
}
//此时 $value = &$arr1[1] ,后面改变$value的值就会改变$arr1[1]元素的值。
$arr2 = [10, 20, 30]; foreach ($arr2 as $value) { var_dump($arr1); }

 

我们发现在循环$arr2时,$arr2元素复制给$value后,同时$arr1的最后一个元素的值也发生变化,此时等于$arr2此时指针对应元素的值。依次推,$arr1最后一个元素的值 = $arr2元素的最后一个值。

解决方法,使用unset()释放元素, 或者循环第2个数组的时候,使用不同的临时变量

$arr1 = [1, 2];
foreach($arr1 as $key => &$value) {
    $value = $value + 1;
}
unset($value);
$arr2 = [10, 20, 30];
foreach ($arr2 as $value) {
    var_dump($arr1);
}



posted on 2019-12-17 22:42  追风的浪子  阅读(377)  评论(0编辑  收藏  举报

导航