Welcome Guest, Not a member yet? Register   Sign In
Iterating through objects by reference
#1

[eluser]Xeoncross[/eluser]
I am getting lost trying to figure out how I can iterate though a class and change the values by reference. I know that in PHP5 all variables that point to an object use a handle that points to the object - rather than duplicating it like in php 3-4.

This problem comes from the fact that I am going over weird objects (simplexml) and such that don't have standard class keys and such. A var dump shows keys => values but the when I test the object those keys don't exist.

Code:
foreach($xml->something as $key => &$item) {
    $item = 'new';
}

//print "new"
print $xml->something->$key;

Here is an error I get with the above code
Quote:Fatal error: An iterator cannot be used with foreach by reference

I can avoid that error with a little JSON trick that converts a SimpleXML object to a plain stdclass() - but it still doesn't work.
Code:
$xml = json_decode(json_encode($xml));

Here is another weird one - the first line sends a notice error about how there is no such thing. But the second one deletes that value from the object that the first line said doesn't exist! (I know it has a value btw)

Code:
if($rss->item[$key]) {
    unset($rss->item[$key]);
}
#2

[eluser]brianw1975[/eluser]
i think you'll have to do something like this...

foreach($xml->something as $key => $item) {
$xml->set($key,'new');
//or
$xml->something->set($key,'new');
}

//print "new"
print $xml->something->$key;

or i could be completely wrong lol
#3

[eluser]Xeoncross[/eluser]
Ok, I think that if you iterate though an object it automatically create the values by reference. The problem was that I wasn't returning the value in a function.

Here is what I was doing.
Code:
foreach($xml->something as $key => &$item) {
    sanitize_text($item);
    //or
    //$item = saintize_text($item);
}

Nither of those worked - but it was the fault of my function! I was trying to do it like this:
Code:
function sanitize_text(&$text){
    //for file_names_make_it_underscore
    trim(str_replace('__', '_', preg_replace("/([^a-z0-9\.]+)/i", '_', $text)));
}
When it should have been like this:
Code:
function sanitize_text($text){
    //for file_names_make_it_underscore
    return trim(str_replace('__', '_', preg_replace("/([^a-z0-9\.]+)/i", '_', $text)));
}

Ok, so when iterating over an object using a foreach php does it by ref. But PHP 5 no longer plays nice with function arguments by reference.

It also seems to be impossible to "unset" an property of an object with unset(). This might have to do with the variable scope unset deals with.

Code:
foreach($xml->something as $key => $item) {
    unset($item);
    //but the var still exists...

    $item = 'new';
    //Yet this modifies the value of $xml->something[$key]!?
}
What's going on!?
#4

[eluser]Xeoncross[/eluser]
And try to figure this one out!

Code:
foreach($rss->item as $key => $item) {
    
    //Works with no errors
    if(empty($item->title)) {
        unset($rss->item[$key]);
        continue;
    }
    
    //No errors - but doesn't delete it
    if(empty($item->title)) {
        unset($item);
        continue;
    }
    
    //Works with no errors
    if(empty($item->title)) {
        if(!empty($rss->item[$key])) {
            unset($rss->item[$key]);
        }
        continue;
    }
    
    //Works with an error about "Undefined offset"
    if(!empty($item->title)) {
        if($rss->item[$key]) { //Notice "undefined offset"!?
            unset($rss->item[$key]); //But this removes that offset!? What the?
        }
        continue;
    }
}




Theme © iAndrew 2016 - Forum software by © MyBB