2010-11-24 57 views
2

我一直試圖修改使用PHP嵌套的foreach循環.. 內指針下面一行但似乎並沒有工作價值:PHP的foreach和引用

// Assign a the attribs value to the array 
$link_row['value'] = $args[ $u_value ]; 

變量的$ args [$ u_value]填充,可以是沒有問題的輸出,但是當我把它添加到$ link_row引用它只是似乎沒有設置..

foreach ($unique_links as $link_id => &$link_attr) 
    { 
    foreach($link_attr as &$link_row) 
    { 
     foreach($link_row as $u_attr => &$u_value) 
     { 
      if ($u_attr == 'attribute_name') 
      {    

       // Assign a the attribs value to the array 
       $link_row['value'] = $args[ $u_value ]; 

       // If one of the values for the unique key is blank, 
       // we can remove the entire 
       // set from being checked 
       if (!isset($args[ $u_value ])) 
       { 
       unset($unique_links[$link_id]); 
       } 
      } 
     } 
    } 
    } 
+1

也許可以接受的答案還沒有給出? – Lee 2010-11-24 14:39:07

回答

0

由於我看不到你的陣列,我不知道哪個是整數,哪個是關聯的等等。

據我所見,沒有任何理由需要$ u_value的引用。它沒有造成任何傷害,但兩種方式都沒有區別。

更重要的是,任何時候你的第二個if條件將是真實的你達到就行了

$link_row['value'] = $args[ $u_value ]; 

也許你之前想使用

$link_row['value'] = isset($args[$u_value]) ? $args[ $u_value ] : "NOT PRESENT"; 

的你將有一個錯誤你提到的行似乎工作得很好。

我的代碼:

$args = array(100,200,300,400,500); 
    $unique_links = array (array( 'a' => array('attribute_name' => 1,'x' => 2, 'y' => 3, 'z' =>4), 
            'b' => array('attribute_name' => 3,'x' => 2, 'y' => 3, 'z' =>4), 
            'c' => array('attribute_name' => 0,'x' => 2, 'y' => 3, 'z' =>4), 
            'd' => array('attribute_name' => 7,'x' => 2, 'y' => 3, 'z' =>4), 
            'e' => array('attribute_name' => 1,'x' => 2, 'y' => 3, 'z' =>4) 

            ));         
    echo_r($unique_links); 
    foreach ($unique_links as $link_id => &$link_attr) 
    { 
     foreach($link_attr as &$link_row) 
     { 
      foreach($link_row as $u_attr => $u_value) 
      { 
       echo "&nbsp&nbsp&nbsp&nbsp $u_attr is $u_value <br />"; 
       if ($u_attr == 'attribute_name') 
       { 

        // Assign a the attribs value to the array 
        $link_row['value'] = isset($args[$u_value]) ? $args[ $u_value ] : "NOT PRESENT"; 

        // If one of the values for the unique key is blank, we can remove the entire 
        // set from being checked 
        if (!isset($args[ $u_value ])) 
        { 
         //echo "want to kill: $link_id <br />"; 
         //unset($unique_links[$link_id]); 
        } 
       } 
      } 
      echo "<br />"; 
     } 
    } 
    echo_r($unique_links); 

我的輸出:

Array 
(
[0] => Array 
    (
     [a] => Array 
      (
       [attribute_name] => 1 
       [x] => 2 
       [y] => 3 
       [z] => 4 
      ) 

     [b] => Array 
      (
       [attribute_name] => 3 
       [x] => 2 
       [y] => 3 
       [z] => 4 
      ) 

     [c] => Array 
      (
       [attribute_name] => 0 
       [x] => 2 
       [y] => 3 
       [z] => 4 
      ) 

     [d] => Array 
      (
       [attribute_name] => 7 
       [x] => 2 
       [y] => 3 
       [z] => 4 
      ) 

     [e] => Array 
      (
       [attribute_name] => 1 
       [x] => 2 
       [y] => 3 
       [z] => 4 
      ) 

    ) 

) 

attribute_name is 1 
x is 2 
y is 3 
z is 4 
value is 200 

attribute_name is 3 
x is 2 
y is 3 
z is 4 
value is 400 

attribute_name is 0 
x is 2 
y is 3 
z is 4 
value is 100 

attribute_name is 7 
x is 2 
y is 3 
z is 4 
value is NOT PRESENT 

attribute_name is 1 
x is 2 
y is 3 
z is 4 
value is 200 

Array 
(
[0] => Array 
    (
     [a] => Array 
      (
       [attribute_name] => 1 
       [x] => 2 
       [y] => 3 
       [z] => 4 
       [value] => 200 
      ) 

     [b] => Array 
      (
       [attribute_name] => 3 
       [x] => 2 
       [y] => 3 
       [z] => 4 
       [value] => 400 
      ) 

     [c] => Array 
      (
       [attribute_name] => 0 
       [x] => 2 
       [y] => 3 
       [z] => 4 
       [value] => 100 
      ) 

     [d] => Array 
      (
       [attribute_name] => 7 
       [x] => 2 
       [y] => 3 
       [z] => 4 
       [value] => NOT PRESENT 
      ) 

     [e] => Array 
      (
       [attribute_name] => 1 
       [x] => 2 
       [y] => 3 
       [z] => 4 
       [value] => 200 
      ) 

    ) 

) 

我註釋掉unnset,因爲它似乎全殺陣,不只是你想要的部分。我猜它是由於殺死你當前正在迭代的部分而造成的一些奇怪的行爲。

+0

感謝您抽出時間看......看起來問題在於未設置本身進入它更多一點..未設置似乎殺死實際上增加的價值.. – Lee 2010-11-24 15:27:32

0

我想你可能會覆蓋在循環的價值。爲了驗證這一點,你可以做這樣的事情

$link_row['value'] = $args[ $u_value ]; 

更改爲

$link_row[] = $args[ $u_value ]; 

然後外面的循環添加此

echo "Link Row Value(s):<pre>".print_r($link_row,true)."</pre><br />\n"; 

這將顯示所有正在價值觀cast/set to $ link_row ['value'],如果您看到多個索引值被覆蓋

+0

我不認爲這是一個問題。爲了$ link_row ['value']被寫入兩次,在同一個數組中必須有兩個名爲'attribute_name'的鍵 – 2010-11-24 14:39:04

3

必須總是foreach中使用它們之後的未設置變量。即使你有兩個foreach(..)陳述一個接一個地。即使在另一個foreach(..)內有foreach(..)沒有例外!

foreach ($unique_links as $link_id => &$link_attr) 
{ 
foreach($link_attr as &$link_row) 
{ 
    foreach($link_row as $u_attr => &$u_value) 
    { 
     if ($u_attr == 'attribute_name') 
     {    

      // Assign a the attribs value to the array 
      $link_row['value'] = $args[ $u_value ]; 

      // If one of the values for the unique key is blank, 
      // we can remove the entire 
      // set from being checked 
      if (!isset($args[ $u_value ])) 
      { 
      unset($unique_links[$link_id]); 
      } 
     } 
    } 
    unset($u_value); // <- this is important 
} 
unset($link_row); // <- so is this 
} 
unset($lnk_attr); // <- and so is this, even if you reached the end of your program or the end of a function or a method and even if your foreach is so deeply indented or on such a long line that you're not sure what code might follow it, because another developer (maybe even you) will come back and read the code and he might not see that you used a reference in a foreach 

這裏還有一個有趣的一段代碼,不久前搞砸了一個大項目:

foreach ($data as $id => &$line) { 
    echo "This is line {$id}: '{$line}'\n"; 
    $line .= "\n"; 
} 

echo "And here is the output, one line of data per line of screen:\n"; 

foreach ($data as $id => &$line) { 
    echo $line; 
} 

有人第一foreach(..)真的搞砸了數據之後並沒有unset($line)事實該數組,因爲&$line是一個參考,第二個foreach(..)爲它指定了一個不同的值,因爲它循環遍歷數據,並且它保持覆蓋最後一行數據。