我有一組存儲在對象中的Db結果。我需要遍歷結果並檢查屬性(使用另一個數據庫查詢),然後使用if語句從對象中刪除項目。這裏是我正在嘗試的簡化版本:從循環中的對象中移除項目
foreach ($products as $product) {
if(!$product->active) {
unset($product);
}
}
print_r($products);
但是,當我print_r的項目仍然在對象中。我感到困惑。
我有一組存儲在對象中的Db結果。我需要遍歷結果並檢查屬性(使用另一個數據庫查詢),然後使用if語句從對象中刪除項目。這裏是我正在嘗試的簡化版本:從循環中的對象中移除項目
foreach ($products as $product) {
if(!$product->active) {
unset($product);
}
}
print_r($products);
但是,當我print_r的項目仍然在對象中。我感到困惑。
那是預期的行爲。有
foreach ($products as $key => $product) {
if(!$product->active) {
unset($product[$key]);
}
}
第二種方法是使用reference
foreach ($products as &$product) {
if(!$product->active) {
unset($product);
}
}
試試這個:
// $id is the key, $product is the value
foreach ($products as $id => $product) {
if(!$product->active) {
unset($products[$id]);
}
}
你不能取消設置變量本身。您需要使用foreach
語法,還爲您提供了該項目的關鍵,並用它來取消設置鍵陣列上:
foreach ($products as $key => $product) {
if(!$product->active) {
unset($products[$key]);
}
}
使用此行:
foreach ($products as &$product)
你要明白,你重置對象在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),您將從內存中取消設置對象引用,因爲沒有指向它。
希望能讓它更清晰...
祝你好運
看起來像問題一樣的代碼。我很困惑,這是答案。 – Dobler
@Dobler - 注意'&'在'foreach($ products as&$ product)'。這意味着數據可以被修改。 –
在第一個例子中,它將是'unset($ products [$ key]);'(帶有尾部s)。 – nanocv