
{"id":1856,"date":"2016-01-02T18:24:07","date_gmt":"2016-01-02T23:24:07","guid":{"rendered":"http:\/\/www.ikriv.com\/blog\/?p=1856"},"modified":"2016-01-02T18:24:07","modified_gmt":"2016-01-02T23:24:07","slug":"php-simplexml-is-broken-part-1","status":"publish","type":"post","link":"https:\/\/ikriv.com\/blog\/?p=1856","title":{"rendered":"PHP SimpleXML is broken: Part 1"},"content":{"rendered":"<p>The following code <b>does not<\/b> work as expected:<\/p>\n<p><code><\/p>\n<pre>\n$xml = simplexml_load_string(\"&lt;root&gt;&lt;a\/&gt;&lt;b&gt;text&lt;\/b&gt;&lt;\/root&gt;\");\n$node = $xml->xpath(\"\/root\/a\")[0];\n<b>if ($node)<\/b> process($node); <font color=\"red\">\/\/ process($node) may not be called for some valid nodes<\/font><\/pre>\n<p><\/code><\/p>\n<p>Unlike most other objects, <code>SimpleXmlElement<\/code> may evaluate as <b>false<\/b> even when it is not null. Specifically, <code>SimpleXmlElements<\/code> representing empty tags (like &#8220;&lt;a \/&gt;) will evaluate as <b>false<\/b>, so <code>process($node)<\/code> won&#8217;t be called for them.<\/p>\n<p>Yes, they made a special case for it in the language definition. E.g. <code>DOMElement<\/code> representing an empty tag won&#8217;t evaluate to false, at least not according to the documentation.<\/p>\n<p>So, in my previous post &#8220;Node is null&#8221; should read &#8220;Node evaluates to false&#8221;, but it is still a bug, since it was not an empty tag.<\/p>\n<p>When you write <code>if (something)<\/code> that something will be converted to Boolean per the below conversion rules. Most of them make sense, but some of them totally don&#8217;t. If you want to check for <b>null<\/b>, you&#8217;d better do it explicitly: <code>if (something !== null)<\/code>.<\/p>\n<h2>PHP Boolean Conversion Rules<\/h2>\n<p>Per the <a href=\"http:\/\/php.net\/manual\/en\/language.types.boolean.php\">PHP documentation on Boolean<\/a> (comments are mine):<\/p>\n<p>When converting to boolean, the following values are considered <b>FALSE<\/b>:<\/p>\n<table>\n<tr>\n<td>the boolean <b>FALSE<\/b> itself<\/td>\n<td>Totally makes sense<\/td>\n<\/tr>\n<tr>\n<td>the integer 0 (zero)<\/td>\n<td>Like in C\/C++, so it is expected, even if may not make perfect sense<\/td>\n<\/tr>\n<tr>\n<td>the float 0.0 (zero)<\/td>\n<td>Like in C\/C++, so it is expected, even though it makes even less sense<\/td>\n<\/tr>\n<tr>\n<td><font color=\"orange\">the empty string<\/font><\/td>\n<td><font color=\"orange\">Not like in C\/C++, but sort of makes sense<\/td>\n<\/tr>\n<tr>\n<td><font color=\"red\">and the string &#8220;0&#8221;<\/font><\/td>\n<td><font color=\"red\">Why?! Because it represents integer 0? How about string &#8220;0.0&#8221; then? Or string &#8220;false&#8221;?<\/td>\n<\/tr>\n<tr>\n<td><font color=\"orange\">an array with zero elements<\/font><\/td>\n<td><font color=\"orange\">Sort of makes sense<\/font><\/td>\n<\/tr>\n<tr>\n<td>an object with zero member variables (PHP 4 only)<\/td>\n<td>Does not make sense, but they deprecated it<\/td>\n<\/tr>\n<tr>\n<td>the special type NULL (including unset variables)<\/td>\n<td>Totally makes sense<\/td>\n<\/tr>\n<tr>\n<td><font color=\"red\">SimpleXML objects created from empty tags<\/font><\/td>\n<td><font color=\"red\">Why?! Who came up with this wonderful idea?<\/td>\n<\/tr>\n<\/table>\n<p>Rest in peace, dear rule of least astonishment. You should never have ventured in that cruel PHP land.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The following code does not work as expected: $xml = simplexml_load_string(&#8220;&lt;root&gt;&lt;a\/&gt;&lt;b&gt;text&lt;\/b&gt;&lt;\/root&gt;&#8221;); $node = $xml->xpath(&#8220;\/root\/a&#8221;)[0]; if ($node) process($node); \/\/ process($node) may not be called for some valid nodes Unlike most other <a href=\"https:\/\/ikriv.com\/blog\/?p=1856\" class=\"more-link\">[&hellip;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[4,5,15],"tags":[],"class_list":["entry","author-ikriv","post-1856","post","type-post","status-publish","format-standard","category-hack","category-dev","category-webdev"],"_links":{"self":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1856","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1856"}],"version-history":[{"count":0,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1856\/revisions"}],"wp:attachment":[{"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1856"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1856"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ikriv.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1856"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}