The following code does not work as expected:
$xml = simplexml_load_string("<root><a/><b>text</b></root>"); $node = $xml->xpath("/root/a")[0]; if ($node) process($node); // process($node) may not be called for some valid nodes
Unlike most other objects, SimpleXmlElement
may evaluate as false even when it is not null. Specifically, SimpleXmlElements
representing empty tags (like “<a />) will evaluate as false, so process($node)
won’t be called for them.
Yes, they made a special case for it in the language definition. E.g. DOMElement
representing an empty tag won’t evaluate to false, at least not according to the documentation.
So, in my previous post “Node is null” should read “Node evaluates to false”, but it is still a bug, since it was not an empty tag.
When you write if (something)
that something will be converted to Boolean per the below conversion rules. Most of them make sense, but some of them totally don’t. If you want to check for null, you’d better do it explicitly: if (something !== null)
.
PHP Boolean Conversion Rules
Per the PHP documentation on Boolean (comments are mine):
When converting to boolean, the following values are considered FALSE:
the boolean FALSE itself | Totally makes sense |
the integer 0 (zero) | Like in C/C++, so it is expected, even if may not make perfect sense |
the float 0.0 (zero) | Like in C/C++, so it is expected, even though it makes even less sense |
the empty string | Not like in C/C++, but sort of makes sense |
and the string “0” | Why?! Because it represents integer 0? How about string “0.0” then? Or string “false”? |
an array with zero elements | Sort of makes sense |
an object with zero member variables (PHP 4 only) | Does not make sense, but they deprecated it |
the special type NULL (including unset variables) | Totally makes sense |
SimpleXML objects created from empty tags | Why?! Who came up with this wonderful idea? |
Rest in peace, dear rule of least astonishment. You should never have ventured in that cruel PHP land.