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: Bogus
Type: Bug
Package: SimpleXML related
PHP Version: 5.3SVN-2010-07-27 (SVN)
Block user comment: N
New Comment:
Ok, I well-understand the problem. So, how can I identify a XML node
precisely? Thanks.
Previous Comments:
------------------------------------------------------------------------
[2010-07-28 15:25:41] ivan dot enderlin at hoa-project dot net
Why you can't fix this in a good way? What does it mean :-)?
------------------------------------------------------------------------
[2010-07-28 14:18:09] [email protected]
As runpac314 this is expected and we can't "fix" this in a good way.
------------------------------------------------------------------------
[2010-07-28 11:22:47] ivan dot enderlin at hoa-project dot net
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.
------------------------------------------------------------------------
[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