如果我遍历一个数组两次,一次通过引用然后按值迭代,如果我为每个循环使用相同的变量名,PHP将覆盖数组中的最后一个值。通过示例最好地说明了这一点:
$array = range(1,5);
foreach($array as &$element)
{
$element *= 2;
}
print_r($array);
foreach($array as $element) { }
print_r($array);
输出:
数组([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 )
数组([0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 8 )
请注意,我不是在寻找解决方案,我希望了解为什么会发生这种情况。另请注意,如果每个循环中的变量名称都不是$element
,则不会发生这种情况,因此我猜测它与$element
仍然在范围内并且在结束后的引用有关。第一个循环。
答案 0 :(得分:7)
在第一个循环之后,$ element仍然是对$ array的最后一个元素/值的引用 当使用var_dump()而不是print_r()
时,可以看到array(5) {
[0]=>
int(2)
...
[4]=>
&int(2)
}
请注意&在&int(2)
使用第二个循环,您可以为$ element指定值。由于它仍然是一个参考,因此数组中的值也会发生变化。尝试使用
foreach($array as $element)
{
var_dump($array);
}
作为第二个循环,你会看到。
所以它和
$array = range(1,5);
$element = &$array[4];
$element = $array[3];
// and $element = $array[4];
echo $array[4];
(只有循环和乘法...嘿,我说“或多或少”; - ))
答案 1 :(得分:5)
这是an explanation from the man himself:
$y = "some test"; foreach ($myarray as $y) { print "$y\n"; }
此处
$y
是一个符号表条目,引用包含“some”的字符串 测试“。在第一次迭代中,你基本上做了:$y = $myarray[0]; // Not necessarily 0, just the 1st element
现在与
$y
相关联的存储 被来自的值覆盖$myarray
。如果与$y
相关联 通过一些其他存储 参考,存储将是 改变。现在让我们说你这样做:
$myarray = array("Test"); $a = "A string"; $y = &$a; foreach ($myarray as $y) { print "$y\n"; }
此处
$y
与此相关联 通过引用存储为$a
第一次迭代时:$y = $myarray[0];
“Test”字符串唯一可以的地方 go进入与之关联的存储
$y
。
答案 2 :(得分:1)
这是解决此问题的方法:
foreach($array as &$element)
{
$element *= 2;
}
unset($element); #gets rid of the reference and cleans the var for re-use.
foreach($array as $element) { }