PHP语言中foreach引用的 “坑”

@心欲无痕  July 19, 2018

foreach坑解读

阅读下面的源代码,下面代码的运行结果并解析其中的缘由:

$arr = [ 11, 22, 33 ];

foreach($arr as &$val)
{
    echo $val . ' ';
}

echo PHP_EOL;

foreach($arr as $val)
{
    echo $val . PHP_EOL;
}

答案:

11 22 33

11 22 22

解析:

由于在PHP底层C语言的实现中,在每一个 foreach循环中,会保留一个全局变量,但是这个全局变量未被销毁所导致,所有在第一个循环的结束后,$val保留的是数组 $arr 的最后一个元素33的引用,在第二个数组的foreach 循环中,每一次都会把数组的元素赋值给数组的第三个元素,当赋值到倒数第二个的时候,此时倒数第一个与倒数第二个值是一样的,都是倒数第二个的值,示意如下:

$arr = [ 11, 22, 33 ];

foreach($arr as &$val)
{
    echo $val;
}

// 运行到此处的时候, $val = &$arr[2],所以下面的foreach循环就是依次把 `11` 、`22` 赋值给 $arr[2],因此就造成了:`11`、`22`、`22`的结果。

foreach($arr as $val)
{
    echo $val . PHP_EOL;
}

上面的代码可以更改为对称的代码:

$arr = [ 11, 22, 33 ];

$val = &$arr[2]

foreach($arr as $val)
{
    echo $val . PHP_EOL;
}

结果是一样的。怎么样?知道原因了吗?,所以这里建议 PHPer开发的时候,如果foreach循环使用了引用的话,每次foreach之后,都手工卸载 unset 变量的引用:

$arr = [ 11, 22, 33 ];

foreach($arr as &$val)
{
    echo $val;
}

unset($val);

foreach($arr as $val)
{
    echo $val . PHP_EOL;
}

评论已关闭