php 从循环中的对象中删除项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7843157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Removing an item from object in a loop
提问by Alex
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:
我有一组存储在对象中的 Db 结果。我需要遍历结果并检查一个属性(使用另一个 DB 查询),然后使用 if 语句从对象中删除该项目。这是我正在尝试的简化版本:
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.
但是,当我 print_r 项目仍然在对象中。我越来越糊涂了。
回答by realshadow
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);
}
}
回答by Mathieu Dumoulin
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:
您需要了解取消设置对象在 php 中没有任何影响。首先,让我用 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.
$a 将首先复制到内存中。它不是一个蛮力复制,它只复制对数据的引用并增加内存中数组(1,2,3,4,5)的使用计数。在 $b 中,您将拥有在 $a 中找到的数据的副本。因此,从内存中取消设置它只会说,嘿,从 $a 的副本内部取消设置 $b。因此,真正的 $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.
然后在这里您将在内存中拥有 $a 的副本。Foreach 将在该副本上迭代(循环)并为您提供复制到 $b 中的每个元素 $a 的键。当您 unset($a[$key]) 时,您告诉 php 影响 $a 中的数组,该数组在 foreach 启动时被复制,但是现在,您使用 $key 引用 $a 中的元素,而不是影响副本一个真正存在于内存中并且您将可以访问的。
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).
现在对于第二部分,如果我们查看对象...取消设置对象没有任何影响,因为包含对象的变量只是对内存中带有计数的数据的引用。如果你 $a = new Object() 然后 $b = $a,你就创建了一个对该对象的新引用,同时保持它的完整性(不复制)。
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.
如果您要取消设置($a),您只会取消对对象的引用,而 $b 仍会指向内存中的该对象。如果您取消设置($b),那么您将从内存中取消设置对象引用,因为没有任何内容指向它。
Hope that makes it clearer...
希望能让它更清楚...
Good luck
祝你好运
回答by Alon Eitan
try this:
尝试这个:
// $id is the key, $product is the value
foreach ($products as $id => $product) {
if(!$product->active) {
unset($products[$id]);
}
}
回答by Jon
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
同样为您提供项目键的语法,并使用它来取消设置数组上的键:
foreach ($products as $key => $product) {
if(!$product->active) {
unset($products[$key]);
}
}
回答by Aurelio De Rosa
Use this line instead:
改用这一行:
foreach ($products as &$product)
回答by slevy1
Alternatively, you can change the loop from using a foreach and operate directly on the array using a for-loop as follows:
或者,您可以将循环从使用 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);
See live code.
查看实时代码。