2011-10-20 23 views
2

我有一組存儲在對象中的Db結果。我需要遍歷結果並檢查屬性(使用另一個數據庫查詢),然後使用if語句從對象中刪除項目。這裏是我正在嘗試的簡化版本:從循環中的對象中移除項目

foreach ($products as $product) { 

    if(!$product->active) { 
     unset($product); 
    } 

} 
print_r($products); 

但是,當我print_r的項目仍然在對象中。我感到困惑。

回答

11

那是預期的行爲。有

foreach ($products as $key => $product) { 

    if(!$product->active) { 
     unset($product[$key]); 
    } 

} 

第二種方法是使用reference

foreach ($products as &$product) { 

    if(!$product->active) { 
     unset($product); 
    } 

} 
+0

看起來像問題一樣的代碼。我很困惑,這是答案。 – Dobler

+0

@Dobler - 注意'&'在'foreach($ products as&$ product)'。這意味着數據可以被修改。 –

+1

在第一個例子中,它將是'unset($ products [$ key]);'(帶有尾部s)。 – nanocv

1

試試這個:

// $id is the key, $product is the value 
foreach ($products as $id => $product) { 
    if(!$product->active) { 
     unset($products[$id]); 
    } 
} 
1

你不能取消設置變量本身。您需要使用foreach語法,還爲您提供了該項目的關鍵,並用它來取消設置鍵陣列上:

foreach ($products as $key => $product) { 
    if(!$product->active) { 
     unset($products[$key]); 
    } 
} 
2

使用此行:

foreach ($products as &$product) 
2

你要明白,你重置對象在PHP沒有效果做你想做的兩種主要方式。首先,讓我解釋一下你用foreach一個關鍵細節:

如果你這樣做:

$a = array(1,2,3,4,5); 
foreach($a as $b){ 
    unset($b); 
} 

$一個將首先在內存中複製。它不是一個粗暴的拷貝,它只是複製對數據的引用,並增加內存中數組(1,2,3,4,5)的使用次數。在$ b內部,您將擁有$ a中的數據副本。因此,從內存中取消設置只會說,嘿,從$ a副本中取消設置$ b。因此,在實際的$ a中完全沒有改變。

如果你做的事:

$a = array(1,2,3,4,5); 
foreach($a as $key => $b){ 
    unset($a[$key]); 
} 

然後在這裏你將有一個$副本在內存中。 Foreach將對該副本進行迭代(循環),併爲每個元素$ a提供密鑰,並將其複製到$ b中。當您取消設置($ a [$ key])時,您告訴php會影響$ a中的數組,並在foreach啓動時被複制,但現在,您不再影響副本,而是使用$ key引用$一種真正存在於記憶中的東西,你將有機會獲得。

現在,對於第二部分,如果我們查看對象...取消設置對象不起作用,因爲包含對象的變量只是對帶有計數的內存中的數據的引用。如果你$ a = new Object()然後$ b = $ a,你創建一個新的對該對象的引用,同時保持它不變(不被複制)。

如果您要取消設置($ a),則只會取消對該對象的引用,並且$ b仍然會指向該內存中的該對象。如果您未設置($ b),您將從內存中取消設置對象引用,因爲沒有指向它。

希望能讓它更清晰...

祝你好運