从循环中的对象中删除项目

时间:2011-10-20 22:46:08

标签: php loops

我有一组存储在对象中的Db结果。我需要遍历结果并检查属性(使用另一个数据库查询),然后使用if语句从对象中删除项目。这是我正在尝试的简化版本:

foreach ($products as $product) {

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

}
print_r($products);

然而,当我print_r时,项目仍在对象中。我很困惑。

6 个答案:

答案 0 :(得分:12)

这是预期的行为。做你想做的事有两种主要方式

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

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

}

第二种方式是使用reference

foreach ($products as &$product) {

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

}

答案 1 :(得分:3)

您需要了解取消设置对象对php没有影响。首先让我用FOREACH向您解释一个关键细节:

如果你这样做:

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

$ a将首先复制到内存中。它不是一个粗略的副本,它只复制对数据的引用并增加内存中数组(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]);
}

然后在这里你会得到$ a的内存副本。 Foreach将对该副本进行迭代(循环),并为每个元素$ a提供密钥,将其复制到$ b中。当你取消设置($ a [$ key])时,你告诉php影响在foreach启动时复制的$ a中的数组,但是现在,你使用$ key来引用$中的元素而不是影响副本。一个真正存在于内存中的,你将有权访问。

现在对于第二部分,如果我们查看对象...取消设置对象没有任何效果,因为包含对象的变量只是对带有计数的内存中的数据的引用。如果$ a = new Object()然后$ b = $ a,则创建对该对象的新引用,同时保持其完整(未复制)。

如果要取消设置($ a),则只会取消设置对象的引用,而$ b仍会指向内存中的该对象。如果取消设置($ b),则会从内存中取消设置对象引用,因为没有任何内容指向它。

希望能让它更清晰......

祝你好运

答案 2 :(得分:2)

请改用此行:

foreach ($products as &$product)

答案 3 :(得分:1)

试试这个:

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

答案 4 :(得分:1)

您无法取消设置变量本身。您需要使用foreach语法,该语法还为您提供项目的密钥,并使用它来取消设置数组上的密钥:

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

答案 5 :(得分:0)

或者,您可以使用foreach更改循环,并使用for循环直接在数组上操作,如下所示:

<?php

$o1 = new stdClass;
$o2 = new stdClass;
$o3 = new stdClass;

$o1->active = false;
$o2->active = true;
$o3->active = true;


$products = [$o1, $o2, $o3];


for($i=0, $max=count($products); $i < $max; $i++) {
        if (!($products[$i]->active)) {
            unset($products[$i]);
        }
}
print_r($products);

// re-index:

$improvedProducts = array_values($products);
print_r($improvedProducts);

请参阅live code