I'm posting this solution in advance for the benefit of others who might trip over this SimpleXML issue.
Drupal 6 automatically passes cache_save and cache_get arguments through PHP's serialize/unserialize functions.
If you parse an XML string using SimpleXML, it creates an object with invisible properties that won't show up if you do a print_r().
This object is a built-in object in PHP terminology, and should not be serialized/unserialized. See the discussion here: http://us3.php.net/manual/en/function.serialize.php
In my case I was trying to store a string, but unknowingly I was storing an object. I had parsed an RSS feed using SimpleXML and extracted one element like so:
$status = $statusobject->channel->item[0]->title;
The resulting $status was printable as a string but actually, unbeknownst to me, was an object when passed through D6's cache functions. When D6 attempted to unserialize the stored value, PHP threw an error: "Node no longer exists."
A cast fixed the problem:
$status = (string) $statusobject->channel->item[0]->title;
Comments
Thanks for the information.
Thanks for the information. I should have searched the Drupal forum first after running into this problem. So instead of trying to cache the simpexml object I cache the XML string I receive from an API request and now all works fine.
@yelvington - awesome
@yelvington - awesome troubleshooting! Thanks for writing this up. "Mysterious error" is a perfect description. :)
Alternate way to save string: toXML()
Thanks for saving the day with this post. I definitely spent several hours beating my head against this before finding your note.
An alternate way to deal with a SimpleXML object or a piece of one is to use the SimpleXML method asXML() to deserialize it before caching:
caught me too, but now im stuck
Hey,
so using
$status = $statusobject->channel->item[0]->title;
caught me out too..
but how do i get rid of the
ive disabled and removed the module, cleared the cache, but the error persists..
re: caught me too
@nzpunter: Did you save the SimpleXMLObject to a variable (via variable_set())? If so, you'll need to delete the variable from the variable table in the db, as well.
RE: Variable
This was what got me. Thank you for this reminder.
I'm not able to resolve this problem
I am attempting to extract an attribute using simpleXML, but I am running into the same error that you mentioned. This is the script I am using:
$buzz_media['type'] = (string)$entry->mediacontent->attributes()->type;
I have tried with and without the "(string)", but the results are the same in both cases. Am I misunderstanding the solution you provided?
Thank you
Thanx for the your message, it was very helpfull and informative. I have encountered this problem recently.
Yeah, thanks a lot for
Yeah, thanks a lot for posting an solution for that issue. Helped me a lot :)
Interesting note. Good to
Interesting note. Good to know!
---
Yuriy Babenko | Technical Consultant & Senior Developer
http://yuriybabenko.com
I was getting the same error
I was getting the same error in my logs after building a module which uses SimpleXML. Thank you yelvington and thank you Google for preventing my head from banging against the wall.
Can't unserialize in watchdog log
Hopefully this prevents some more bruised heads.
While debugging, I had asked Watchdog to save a SimpleXMLElement to the log. Due to the reasons described above, it caused the error, and caused it again and again every time I looked at the log.
To solve the problem I looked through the watchdog table until I found a record with SimpleXMLElement in the variables field, deleted the record, and the error went away.
And that made me happy.
Thanks a lot
hi yelvington,
thanks for this awesome info..............
it really works....
thanks once again
Thank you! I was just about
Thank you! I was just about to reinstall the site - Your post saved me several hours.
Cache XML string
Hi,
Thanks for this information.
You can also cache the full XML string and recreate the SimpleXMLElement:
For me it works very well.
Thanks
Thank you yelvington for solution, to get out of hell :) :P.
Casting didn't solve the
Casting didn't solve the problem for me when trying to set an attribute as a string. Seems that an empty object is always returned... just needed to check for existence first. For example: