2014-07-03 58 views
2

我正在测试数组副本上引用的性能/挂钩。我有以下代码:在阵列上奇怪的打印

function ScoreWords($Value){ 
    $WordList = array(
     "Amazing" => 1, 
     "Value" => 300, 
     "Elements" => 30, 
     "Another" => 0 

    ); 

    if (array_key_exists($Value,$WordList)){ 
     return $WordList[$Value]; 
    } 

} 

$array = ["Value","Another",1,2,3,4]; 
echo implode(',', $array), "<br>"; 

foreach ($array as &$value) { 
    ScoreWords($value); 
} 
echo implode(',', $array), "<br>"; 

foreach ($array as $value) { 
    ScoreWords($value); 
}  
echo implode(',', $array), "<br>"; 

但是看起来,上面粘贴的代码工作得很好。输出是:

值,另一个,1,2,3,4-

值,另一个,1,2,3,4-

值,另一个,1,2,3,3-

我发现这是错误的,因为内爆实际上并非必要,但这引发了一个问题。为什么最终印刷品有重复值,而不是4的正确值?不管数组的内容是什么。它似乎将最后一个元素的第二个元素复制为最后一个元素?

+2

阅读[10级最常见的错误PHP程序员制作]这个列表#1(http://www.toptal.com/php/10-most-common-mistakes-php-programmers -make) –

+0

@MarkBaker:哇。这完全解释了这里的确切问题! :-D –

回答

3

发生了什么事情是,在您的第一个foreach之后,$value是对数组中最后一个元素的引用。随着循环的进展,它是对每个元素的引用,直到最后停止。

所以,当第二个foreach运行时,$value仍然是的一个参考。在该循环运行时,它将更新$value,然后更新数组中的最后一个元素。

当它到达最后一个元素时,它从之前的循环迭代中设置为3。所以,这就是为什么最后设置为3。

要解决此问题,请在您的第一个foreach之后unset($value);

+0

哇不知道它是如此不安全 – Fabricator

+1

'var_dump($ array)'会显示该元素确实是一个引用 – Fabricator

1

这里的事情是,你必须unset值,当你按引用传递它:

foreach ($array as &$value) { 
    ScoreWords($value); 
} 
unset($value); // break the reference with the last element 

警告A $值的参考和最后一个数组元素在foreach后保持甚至 循环。建议通过unset()销毁它。

Foreach reference