Edit report at http://bugs.php.net/bug.php?id=52458&edit=1
ID: 52458 Comment by: ivan dot enderlin at hoa-project dot net Reported by: ivan dot enderlin at hoa-project dot net Summary: spl_object_hash() has strange behaviors with SimpleXML Status: Open Type: Bug Package: SimpleXML related PHP Version: 5.3SVN-2010-07-27 (SVN) Block user comment: N New Comment: That's what I thought actually. But is it a normal behavior for SimpleXML to always create a new zval for each node access? I don't think so. Is it embarassing to fix it? Does it create some memory problem? The XML tree is created in memory thanks to libxml, thus if SimpleXML stores zval, I don't see any problem. Your fix is smart and I will use it as a workaround for now. Hope to hear more about it. Previous Comments: ------------------------------------------------------------------------ [2010-07-27 20:28:33] runpac314 at gmail dot com The hash is partially computed with the object handle the zval is pointing to. In the above test script, zvals are destroyed when f() and g() return because they are not referenced anywhere else. When accessing a sxe property through a dim read (->), a new zval with a type IS_OBJECT is created and it's given a new object handle. These object handles are cycling depending on the availability in the store. I do not think it's a bug. It's just how SimpleXML gives access to the internal libxml nodes to the user. There are 2 kinds of hash below. One for each variable ($a and $b). Both are different objects even if the underlying libxml node pointer is the same. $a = $sxe->p; $b = $sxe->p[0]; var_dump(f($a)); var_dump(f($a)); var_dump(f($b)); var_dump(f($b)); var_dump(f($b)); var_dump(f($b)); var_dump(f($b)); var_dump(f($b)); ------------------------------------------------------------------------ [2010-07-27 16:01:24] ivan dot enderlin at hoa-project dot net Description: ------------ Hey :-), spl_object_hash() has strange behaviors with SimpleXML. You know that SimpleXMLElement uses properties to access to its children collection and array-access to reach a specific child into this collection. So, if we want to reach an element, we have to do: $sxe->element[0] for example. Unfortunately, it appears to always return a ânew objectâ according to spl_object_hash(). Please, see the code below. You can notice that $sxe->p has sometimes the same has than $sxe-p[0]. And why $sxe-p[0] has most of the time a different hash? Test script: --------------- <?php $xml = '<?xml version="1.0" encoding="utf-8"?>' . "\n\n" . '<page>' . "\n" . ' <p>Foobar</p>' . "\n" . '</page>'; $sxe = simplexml_load_string($xml); function f ( $e ) { return spl_object_hash($e); } var_dump(f($sxe->p)); var_dump(f($sxe->p)); var_dump(f($sxe->p[0])); var_dump(f($sxe->p[0])); var_dump(f($sxe->p[0])); var_dump(f($sxe->p[0])); var_dump(f($sxe->p[0])); var_dump(f($sxe->p[0])); echo "\n" . 'Light!' . "\n\n"; function g ( $e ) { return substr(f($e), 14, 2); } var_dump(g($sxe->p)); var_dump(g($sxe->p)); var_dump(g($sxe->p[0])); var_dump(g($sxe->p[0])); var_dump(g($sxe->p[0])); var_dump(g($sxe->p[0])); var_dump(g($sxe->p[0])); var_dump(g($sxe->p[0])); Expected result: ---------------- string(32) "000000005cddd92f000000002401191e" string(32) "000000005cddd92f000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd929000000002401191e" Light! string(2) "2f" string(2) "2f" string(2) "29" string(2) "29" string(2) "29" string(2) "29" string(2) "29" string(2) "29" Actual result: -------------- string(32) "000000005cddd92f000000002401191e" string(32) "000000005cddd92f000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd92e000000002401191e" string(32) "000000005cddd92f000000002401191e" string(32) "000000005cddd929000000002401191e" string(32) "000000005cddd92e000000002401191e" string(32) "000000005cddd92f000000002401191e" Light! string(2) "2f" // p string(2) "2f" // p, same hash, oof string(2) "29" // p[0], ok string(2) "2e" // p[0], huh? string(2) "2f" // p[0], has the hash that p⦠why? string(2) "29" // p[0], like the first p[0] string(2) "2e" // p[0], we have a loop here string(2) "2f" // p[0], definitively, we have a loop. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=52458&edit=1