I am trying to count children of a DOMNode
. It appears to give wrong results when I use count
vs traversing or the ->length
property. As if text nodes are not counted.
Consider
<?php
$html = '<p>with <a>link</a> text</p>';
$dom = new DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$paragraph = $dom->firstChild;
$count = 0;
foreach ($paragraph->childNodes as $childNode) {
$count++;
}
echo count($paragraph->childNodes) . "n";
echo $paragraph->childNodes->length . "n";
echo $count . "n";
And the output is:
1
3
3
Is this a bug in Countable
implementation of DOMNodeList
?
2
Answers
As far as I know,
count()
in theDOMNodeList
doesn’t count the number of items in the node list. Instead, it will return 1, indicating that the object is singular. (In some PHP versions, it might return 0).On the other hand, the
length
property ofDOMNodeList
is the correct and reliable way to get the number of nodes in the list. ($paragraph->childNodes->length
)The
Countable
implementation on theDOMNodeList
class was added in PHP 7.2, which was released in November 2017:Until that was added, using
count()
just returned the default value it returned for any non-Countable
object, which is always1
. (Since PHP 8.0, there is no such default, objects that don’t implementCountable
return an error instead.)This means that you are running a version of PHP which has reached end of life – the last version where this code will not give the correct result is PHP 7.1, which last had an official security release in December 2019.
If at all possible, you should be upgrading to a supported PHP version. If you are genuinely unable to do that, you need to be aware that a lot of examples you see, and libraries you try to use, will assume you are on a newer PHP version.