DOMNode children iteration (was Re: array() returns something weird)

From: Date: Mon, 24 Aug 2009 23:22:24 +0000
Subject: DOMNode children iteration (was Re: array() returns something weird)
References: 1 2 3  Groups: php.general 
Request: Send a blank email to php-general+get-297155@lists.php.net to get a copy of this message
Hi Lars and list! New facts about the strange bug initially diagnosed as array() returning NULL: Firstly, the issue is not really about array() returning null, but about full blown UndefinedBehavior(TM) progressively trashing local variables. It just so happened that I noticed it first with a variable to which array() had been assigned just before things began breaking. Secondly, I proudly present the culprit: things break when I iterate over a DOMNode's children *by reference* using firstChild and nextSibling: for($child=&$node->firstChild; $child; $child=&$child->nextSibling) { //processing... } No problems if iteration is done by value or by DOMNodeList (childNodes, DOMXPath...). HOWEVER, I still consider this a bug because it destablizes PHP. After the evil loop has finished, things happen that should never happen, like a variable being NULL immediately after being assigned array(). I attach a demonstration. It is a self-contained commented script that you can execute from command line. Also attached is output on my machine. Best regards, Szczepan Hołyszewski

Attachment: [application/x-php] testme.php
THE GOOD WAY (DOMNodeList): Recursion structure: ->render() ->render() ->render() <- ->render() <- <- <- Transformation result: Some text. [object type='foo' name='bar'][param name='__default_content'] Some parameter text. Some parameter text. [object type='bar' name='nested'][param name='__default_content'] Some nested parameter text. Some nested parameter text. [object type='baz' name='deeply_nested'][param name='__default_content'] [/param][param name='bold']true[/param][/object] More nested parameter text More nested parameter text [/param][/object] [/param][/object] Some more text Success! THE MIXED WAY (DOMNodeList at outermost level, then firstChild/nextSibling by ref): Recursion structure: ->render() ->render() ->render() <- ->render() <- <- <- Transformation result: Some text. [object type='foo' name='bar'][param name='__default_content'] Some parameter text. Some parameter text. __default_content[param name='__default_content']__default_content[/param][/object] [/param][/object] Some more text Is it really a success? THE EVIL WAY (firstChild/nextSibling by ref): Recursion structure: ->render() ->render() ->render() <- ->render() <-
« previous php.general (#297155) next »