我正在编写的一个简单的 php 脚本出现了一些非常奇怪的行为。我将其减少到重新创建错误所需的最低限度:
<?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
)
这是一个错误还是应该发生的一些非常奇怪的行为?
最佳答案
在第一个 foreach 循环之后,$item
仍然是对某个值的引用,该值也被 $arr[2]
使用。因此,第二个循环中的每个 foreach 调用(不通过引用调用)都会用新值替换该值,从而替换 $arr[2]
。
所以循环1,值和$arr[2]
变成$arr[0]
,也就是'foo'。
循环2,value和$arr[2]
变成$arr[1]
,也就是'bar'。
循环3,值和$arr[2]
变成$arr[2]
,也就是'bar'(因为循环2)。
值 'baz' 实际上在第二个 foreach 循环的第一次调用时丢失了。
调试输出
对于循环的每次迭代,我们将回显 $item
的值并递归打印数组 $arr
。
当第一个循环运行时,我们看到这个输出:
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]
相同的位置。
当第二个循环运行时,我们看到这个输出:
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
,因为它只是由该循环的上一次迭代设置的。
这是一个错误吗?
没有。这是引用项目的行为,而不是错误。这类似于运行类似:
for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }
foreach 循环本质上并不特殊,它可以忽略引用的项目。它只是每次都将该变量设置为新值,就像在循环之外一样。
关于PHP Foreach 通过引用传递 : Last Element Duplicating?(错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8220399/