doc-en icon indicating copy to clipboard operation
doc-en copied to clipboard

Mentioned non-existing function RecursiveIteratorIterator::getChildren()

Open martin-kordas opened this issue 4 years ago • 5 comments

From manual page: https://php.net/recursiveiteratoriterator.beginchildren

There is no RecursiveIteratorIterator::getChildren() function on RecursiveIteratorIterator object, only ::callGetChildren().

martin-kordas avatar Jul 15 '21 21:07 martin-kordas

Thanks for that issue. Would you by any chance know how this should be resolved? Should we document getChildren()? I don't have much experience with Spl iterators myself, but I can say that I can definitely call getChildren() on RecursiveIteratorIterator. I don't see it being inherited either. Reflection doesn't show that method either. Is it a magic method?

kamil-tekiela avatar Jul 15 '21 21:07 kamil-tekiela

It seems to me that callGetChildren() calls getChildren() internally. See the following snippet:

$rdi = new RecursiveDirectoryIterator($folder);
$rii = new RecursiveIteratorIterator($rdi);
foreach ($rii as $filename => $file) {
  $rii->callGetChildren();
}

If $folder contains a regular file (not directory), it has no children and UnexpectedValueException is thrown with stack trace reporting that callGetChildren() and then getChildren() have been called. However, there is not any magic __call() method in the stack trace. This is strange, because I also do not see getChildren() method in reflection preview, although it is possible to call it. (Tested with PHP 7.2.30, Win10 x64).

There is even one more docs page where getChildren() method is mentioned: https://www.php.net/manual/en/recursiveiteratoriterator.construct.php

In my opinion, callGetChildren() should only be documented because it is the preferred method intended for overriding.

martin-kordas avatar Jul 15 '21 23:07 martin-kordas

RecursiveIteratorIterator forwards all unknown method calls to the underlying RecursiveIterator, see https://github.com/php/php-src/blob/a733b1ada7895f6fa5e349755a878cae9189e3f5/ext/spl/spl_iterators.c#L892. This doesn't use __call(), but rather an internal overloading mechanism.

(Why? Because SPL.)

nikic avatar Jul 16 '21 13:07 nikic

RecursiveIteratorIterator forwards all unknown method calls to the underlying RecursiveIterator, […]. This doesn't use __call(), but rather an internal overloading mechanism.

I think we should document this in the introduction section.

cmb69 avatar Jul 16 '21 13:07 cmb69

Does that mean that RecursiveIteratorIterator implements RecursiveIterator? Or does it instantiate it internally?

kamil-tekiela avatar Jul 16 '21 14:07 kamil-tekiela