2014-10-28 65 views
3

我來過的情況下,foreach中的值通過引用傳遞以修改元素,然後在代碼的稍後階段,相同的數組再循環做一些計算,但這次元素是按值傳遞的。問題在於PHP在第一個foreach中保留了對數組中最後一個元素的引用,然後將在下一個foreach開始時覆蓋該元素,如果本地變量具有相同的名稱。替代foreach通過引用

示例代碼:

<?php 
$a = array("a" => "foo"); 
$b = array("b" => "bar"); 

$x = array($a, $b); 

foreach ($x as &$y) {} 

print_r($x); 

foreach ($x as $y) {} 

print_r($x); 
?> 

這將產生

 
Array 
(
    [0] => Array 
     (
      [a] => foo 
     ) 

    [1] => Array 
     (
      [b] => bar 
     ) 

) 
Array 
(
    [0] => Array 
     (
      [a] => foo 
     ) 

    [1] => Array 
     (
      [a] => foo 
     ) 

) 

這荒謬PHP手冊

警告一個$值的參考和最後陣列被表示元素在foreach循環之後仍然存在。建議通過unset()銷燬它。

事實上,使用unset($y)將解決此問題。但是這是非常脆弱的,你不能依賴於編程人員總是記住取消設置一個範圍不明顯的變量。所以我的問題是:是否有任何foreach的好替代方案 - 通過引用來消除以後需要取消設置變量?

+1

你給不給上爲什麼它是必要的任何線索的例子在這裏使用參考。 – raina77ow 2014-10-28 11:03:45

+0

'$ a = array(「a」=>「foo」); $ b = array(「b」=>「bar」); $ x = array($ a,$ b);'你確定你不想使用'array_merge();'? – 2014-10-28 11:04:36

+1

@ raina77ow這真的很重要嗎?代碼只是指出了缺陷。所有你需要知道的是變量需要修改。 – jurgemaister 2014-10-28 11:05:55

回答

3

您可以使用array_walk()

array_walk($x, function(&$y) { 
    /* ... */ 
}); 

這使得基準$y本地的,這樣不落的是自動處理的回調函數的範圍。

+0

謝謝。這是我最終使用的。另外值得注意的是,對於外部變量在匿名函數中可用,必須使用['use()'](http://php.net/manual/en/functions.anonymous.php)。 – jurgemaister 2014-10-28 11:27:00

2

您可以使用關聯(索引)的foreach:

foreach ($x as $index=>$y) 
{ 
if ($y=='remove') {unset($x[$index]);} 
} 

這樣你就可以修改原始數組元素的輕鬆......

+0

@ php_coder_3809625不,他要求提供「替代foreach pass by reference」。這是一個有效的答案。 – 2014-10-28 11:14:54