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

发布于 2024-12-10 19:50:17 字数 271 浏览 0 评论 0原文

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

foreach ($products as $product) {

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

}
print_r($products);

但是,当我 print_r 时,项目仍在对象中。我越来越困惑了。

I have a set of Db results that are stored in an object. I need to loop through the results and check a property (using another DB query) and then use an if statement to remove the item from the object. Here is a simplified version of what I'm attempting:

foreach ($products as $product) {

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

}
print_r($products);

However when I print_r the items are still in the object. I'm getting confused.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

虚拟世界 2024-12-17 19:50:17

这是预期的行为。有两种主要方法可以做你想做的事情

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

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

}

第二种方法是使用 reference

foreach ($products as &$product) {

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

}

Thats expected behaviour. There are two main way of doing what you want

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

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

}

Second way would be to use reference

foreach ($products as &$product) {

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

}
欢烬 2024-12-17 19:50:17

您需要了解取消设置对象在 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 将迭代(循环)该副本,并为您提供复制到 $b 中的每个元素 $a 的键。当您 unset($a[$key]) 时,您告诉 php 影响 $a 中的数组,该数组在 foreach 启动时复制,但现在,您使用 $key 来引用 $ 中的元素,而不是影响副本真正存在于内存中并且您可以访问的。

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

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

希望这能让它更清楚......

祝你好运

You need to understand that unsetting an object has no effect in php. First of all let me explain you a crucial detail with FOREACH:

if you do:

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

$a will be first copied in memory. Its not a brute copy per say, it only copies a reference to the data and augments the count of usage of the array(1,2,3,4,5) in memory. Inside of $b, you will have copies of the data found in $a. Therefore, unsetting it from memory only says, hey, unset $b from inside the copy of $a. Therefore, making no change at all in the real $a.

If you were to do:

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

Then here you would have a copy of $a in memory. The Foreach would iterate (loop) on that copy and provide you with keys to each elements $a that gets copied into $b. When you unset($a[$key]) you tell php to affect the array in $a that got copied when the foreach started, but now, instead of affecting the copy, you are using the $key to reference an element in $a that truly exists in memory and that you will have access to.

Now for the second part, if we look at objects... unsetting an object has no effect because variables containing objects are only references to data in memory with a count. If you $a = new Object() and then $b = $a, you create a new reference to that object whilst keeping it intact (not copied).

If you were to unset($a), you would only unset the reference to the object and $b would still point to that object in memory. If you unset($b), you will then unset the object reference from memory because nothing points to it.

Hope that makes it clearer...

Good luck

慵挽 2024-12-17 19:50:17

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

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

You can't unset the variable itself. You need to use the foreach syntax that also gives you the item's key and use that to unset key on the array:

foreach ($products as $key => $product) {
    if(!$product->active) {
        unset($products[$key]);
    }
}
朱染 2024-12-17 19:50:17

使用这一行代替:

foreach ($products as &$product)

Use this line instead:

foreach ($products as &$product)
故事灯 2024-12-17 19:50:17

试试这个:

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

try this:

// $id is the key, $product is the value
foreach ($products as $id => $product) {
    if(!$product->active) {
        unset($products[$id]);
    }
}
帝王念 2024-12-17 19:50:17

或者,您可以更改使用 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);

请参阅 实时代码

Alternatively, you can change the loop from using a foreach and operate directly on the array using a for-loop as follows:

<?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);

See live code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文