Difference between next() and nextElement() in RecursiveIteratorIterator
Question
What is the difference between RecursiveIteratorIterator::next()
and RecursiveIteratorIterator::nextElement()
?
The documentation is slightly less than helpful:
RecursiveIteratorIterator::next():
RecursiveIteratorIterator::next — Move forward to the next element
RecursiveIteratorIterator::nextElement():
RecursiveIteratorIterator::nextElement — Next element
...
Called when the next element is available.
Solution
From looking at the PHP source, it appears that nextElement
is a callback function that can be called "when the next element is available".
288 if (object->nextElement && (object->mode == RIT_SELF_FIRST || object->mode == RIT_CHILD_FIRST)) {
289 zend_call_method_with_0_params(&zthis, object->ce, &object->nextElement, "nextelement", NULL);
290 }
The default nextElement
function in the iterator class doesn't appear to do anything at the moment from looking at spl_iterators.c:801.
Right now it looks like a no-op as there is no way to register your own callback for that function and in the PHP source, it currently does nothing. From looking at the code, if registered, that callback gets called when the iterator moves forward to the next element, prior to acting on the item (e.g. userland code in a foreach loop).
See @RamboCoder's answer for explanation on how to use it.
OTHER TIPS
The template method design pattern crops up in some of the spl classes, this is one occurrence. You're expected to extend RecursiveIteratorIterator to provide implementations for the optional hooks, and then the superclass (RecursiveIteratorIterator) will call them at the appropriate times.
class A extends RecursiveIteratorIterator {
function nextElement() {
echo 'hi';
}
}
$r = new A(new RecursiveArrayIterator([1,2]));
iterator_to_array($r);//hihi
You could think of nextElement() as an event handler, except you need to extend the class to provide an implementation of a handler.
Some of the other methods you can hook into are beginChildren() beginIteration() callHasChildren() etc...