PHP Foreach 通过引用:复制最后一个元素?(漏洞?) [英] PHP Foreach Pass by Reference: Last Element Duplicating? (Bug?)

查看:32
本文介绍了PHP Foreach 通过引用:复制最后一个元素?(漏洞?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编写一个简单的 php 脚本时遇到了一些非常奇怪的行为.我将其减少到重新创建错误所需的最低限度:

I just had some very strange behavior with a simple php script I was writing. I reduced it to the minimum necessary to recreate the bug:

<?php

$arr = array("foo",
             "bar",
             "baz");

foreach ($arr as &$item) { /* do nothing by reference */ }
print_r($arr);

foreach ($arr as $item) { /* do nothing by value */ }
print_r($arr); // $arr has changed....why?

?>

输出:

Array
(
    [0] => foo
    [1] => bar
    [2] => baz
)
Array
(
    [0] => foo
    [1] => bar
    [2] => bar
)

这是一个错误还是一些应该发生的非常奇怪的行为?

Is this a bug or some really strange behavior that is supposed to happen?

推荐答案

在第一个 foreach 循环之后,$item 仍然是对某个值的引用,该值也被 $arr 使用[2].因此,第二个循环中的每个 foreach 调用(不通过引用调用)都会替换该值,从而将 $arr[2] 替换为新值.

After the first foreach loop, $item is still a reference to some value which is also being used by $arr[2]. So each foreach call in the second loop, which does not call by reference, replaces that value, and thus $arr[2], with the new value.

所以循环1,值和$arr[2]变成了$arr[0],也就是'foo'.
循环2,value和$arr[2]变成$arr[1],也就是'bar'.
循环3,value和$arr[2]变成$arr[2],也就是'bar'(因为循环2).

So loop 1, the value and $arr[2] become $arr[0], which is 'foo'.
Loop 2, the value and $arr[2] become $arr[1], which is 'bar'.
Loop 3, the value and $arr[2] become $arr[2], which is 'bar' (because of loop 2).

值 'baz' 实际上在第二个 foreach 循环的第一次调用中丢失了.

The value 'baz' is actually lost at the first call of the second foreach loop.

对于循环的每次迭代,我们将回显 $item 的值并递归打印数组 $arr.

For each iteration of the loop, we'll echo the value of $item as well as recursively print the array $arr.

当第一个循环运行时,我们看到这个输出:

When the first loop is run through, we see this output:

foo
Array ( [0] => foo [1] => bar [2] => baz )

bar
Array ( [0] => foo [1] => bar [2] => baz )

baz
Array ( [0] => foo [1] => bar [2] => baz )

在循环结束时,$item 仍然指向与 $arr[2] 相同的位置.

At the end of the loop, $item is still pointing to the same place as $arr[2].

当第二个循环运行时,我们看到这个输出:

When the second loop is run through, we see this output:

foo
Array ( [0] => foo [1] => bar [2] => foo )

bar
Array ( [0] => foo [1] => bar [2] => bar )

bar
Array ( [0] => foo [1] => bar [2] => bar )

您会注意到每次数组如何将一个新值放入 $item 时,它也会用相同的值更新 $arr[3],因为它们都是仍然指向同一个位置.当循环到达数组的第三个值时,它将包含值 bar,因为它刚刚由该循环的前一次迭代设置.

You'll notice how each time array put a new value into $item, it also updated $arr[3] with that same value, since they are both still pointing to the same location. When the loop gets to the third value of the array, it will contain the value bar because it was just set by the previous iteration of that loop.

没有.这是引用项的行为,而不是错误.它类似于运行以下内容:

No. This is the behavior of a referenced item, and not a bug. It would be similar to running something like:

for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }

foreach 循环本质上并不特殊,它可以忽略引用的项目.它只是每次都将该变量设置为新值,就像在循环之外一样.

A foreach loop isn't special in nature in which it can ignore referenced items. It's simply setting that variable to the new value each time like you would outside of a loop.

这篇关于PHP Foreach 通过引用:复制最后一个元素?(漏洞?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆