Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing an item from object in a loop

Tags:

loops

php

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.

like image 416
Alex Avatar asked Oct 20 '11 22:10

Alex


2 Answers

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

}
like image 101
realshadow Avatar answered Oct 14 '22 02:10

realshadow


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

like image 20
Mathieu Dumoulin Avatar answered Oct 14 '22 04:10

Mathieu Dumoulin