2014-07-03 81 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