从两天开始,我真的对这个感到疯狂。如果有人能给我一个提示,我将不胜感激。我绝对不明白为什么这个PHP代码:
$arr [] = [ "name" => "Chapter 1" ];
$arr [] = [ "name" => "Chapter 2" ];
foreach ( $arr as &$item )
echo $item['name']."<br>";
echo "============<br>";
foreach ( $arr as $item )
echo $item['name']."<br>";
给出以下输出:
Chapter 1
Chapter 2
============
Chapter 1
Chapter 1 (I would expect 'Chapter 2' here)
看起来第一个循环修改了数组,即使循环中没有赋值。奇怪的是,当我删除与号时,一切都按预期工作。
我不明白的是,为什么数组会被修改,即使我没有对引用变量"&$item"变量做任何事情(除了回显它)。
我还尝试了循环之间的 reset()。但它并没有改变任何东西,根据手册,在这种情况下(至少根据我的理解),无论如何都没有必要,因为循环彼此开始并且不以某种方式嵌套。
多谢!
伯恩德
任何循环完成后,其中使用的变量仍然存在。例如:
for( $i=0; $i<10; $i++) {
// do something
}
echo $i; // 10
这同样适用于引用。循环完成后,$item
仍然是对数组中最后一项的引用。因此,当您第二次写入foreach($arr as $item)
时,您现在使用该引用到最后一个元素并重复重新分配它,这会导致数组的最后一个元素被分配(通过引用)与倒数第二个项目相同的东西。
要解决此问题,请务必清理:
unset($item); // delete the reference
从理论上讲,您应该在任何循环后进行清理,但在几乎所有其他情况下,这都无关紧要。只是在这种情况下,它确实如此!
你可以在这里阅读更多 http://pl.php.net/manual/en/control-structures.foreach.php
"为了能够直接修改循环中的数组元素,前面$value &.在这种情况下,该值将通过引用分配。
例:
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)
unset($value); // break the reference with the last element
从技术上讲,数组不会在代码示例中进行修改,但引用点附加到其中一个数组值。 如果将示例修改为:
$arr [] = [ "name" => "Chapter 1" ];
$arr [] = [ "name" => "Chapter 2" ];
echo '<pre>';
var_dump($arr);
foreach ( $arr as &$item )
echo $item['name']."<br>";
echo "============<br>";
var_dump($arr);
foreach ( $arr as $item )
echo $item['name']."<br>";
echo $item['name'];
您可以检查 var 转储输出,并在第二个 var 转储中查看引用指针:
array(2) {
[0]=>
array(1) {
["name"]=>
string(9) "Chapter 1"
}
[1]=>
array(1) {
["name"]=>
string(9) "Chapter 2"
}
}
Chapter 1
Chapter 2
============
array(2) {
[0]=>
array(1) {
["name"]=>
string(9) "Chapter 1"
}
[1]=>
&array(1) {
["name"]=>
string(9) "Chapter 2"
}
}
Chapter 1
Chapter 1
我的理论是,这与PHP内部如何处理引用指针有关。 正如其他人所建议的那样,只需在循环之间运行unset($item)
,您就可以缓解问题。