Anyone that’s used PHP’s DOM XML knows that it’s a deprecated, buggy PoS. An undocumented memory leak in DOM XML resources and an equally undocumented workaround to manually free them are plenty of evidence for this. Spare a thought for those of us who are on supported RHEL4 and stuck with PHP 4 and hence the DOM XML API.
My gripe today is with
create_element_ns. Terence Kearns has a pretty good summary of the issue in his comments. Essentially, you cannot add a namespace to a node with the default prefix in a way that is recognised by the rest of DOM XML. The problem is that supplying an empty
$prefix parameter to
create_element_ns is treated the same as omitting the
$prefix parameter altogether, in which case DOM XML generates a random prefix.
The libxml2 convention is that passing a NULL prefix to xmlNewNs binds the default namespace, while passing an empty string is illegal. Unfortunately, this convention might break a lot of PHP code that relies on DOM XML generating random namespace prefixes, because people are more likely to omit $prefix than to supply an empty string when they want the random-prefix behaviour. However, I figure it’s better to break lazy code than to invert the libxml convention.
My patch changes the DOM XML behaviour so that an empty string prefix such as
$doc->create_element_ns('foo', 'http://example.net', '') activates the old DOM XML random-prefix:
<a1337:foo xmlns:a1337="http://example.net" />
$prefix altogether as in
$doc->create_element_ns('foo', 'http://example.net') binds the default namespace:
<foo xmlns="http://example.net" />