|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2012-07-23 11:16 UTC] alexshock at yandex dot ru
Description: ------------ In PHP 5.4.0 and higher SimpleXMLElement works strange when trying to obtain children nodes (see test.php source for details). Works fine in 5.3.x, I found that this issue occurs after this commit in php git repo: 1e3b32c777829f61fa9a18278e0647e9112d96ea Test script: --------------- https://www.dropbox.com/s/j0i47y7q4n4g0g6/test.php PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 03 19:00:02 2025 UTC |
Confirmed in 5.4.5. In the process of verifying the change(s) that introduced this issue: -------------------------------------------------------------------------------- object(A)#2 (1) { ["@attributes"]=> array(1) { ["attr"]=> string(9) "Some Attr" } } -------------------------------------------------------------------------------- object(A)#3 (2) { ["@attributes"]=> array(1) { ["attr"]=> string(9) "Some Attr" } [0]=> string(10) "Some Value" } --------------------------------------------------------------------------------It causes not only wrong var_dump and print_r, but also wrong boolean cast. Test script: ------------ $xml = <<<XML <?xml version="1.0"?> <a> <b>Some String</b> </a> XML; $b = simplexml_load_string($xml)->xpath('/a/b'); var_dump((string)$b[0]); var_dump((bool)$b[0]); Expected result: ---------------- string(11) "Some String" bool(true) Actual result: -------------- string(11) "Some String" bool(false)The following workaround seems to fix both dumping and type casting: <?php class SimpleXMLElement_CloneFix extends SimpleXMLElement { public function xpath($path) { $result = parent::xpath($path) ?: array(); foreach ($result as $node) { $this->_fixNode($node); } return $result; } protected function _fixNode(SimpleXMLElement $node) { if (!$node && (string)$node) { $dom = dom_import_simplexml($node); $dom->parentNode->replaceChild(clone $dom, $dom); } } } Unfortunately, the same approach does not work for children() method, because of mysterious nature of its returned value. Despite returned object manifests itself as an instance of SimpleXMLElement, it does not behave as such. For instance, it is incompatible with dom_import_simplexml(). So, what kind of SimpleXMLElement is that?