Hi internals,

I'm currently trying to make sure that all internal Traversable classes
implement either Iterator or IteratorAggregate. This is a hard requirement
for userland classes, but internal classes can get away with implementing
only the internal get_iterator() mechanism. (
https://github.com/php/php-src/pull/5216)

One problem I ran into along the way is the SimpleXMLIterator class. A
naive person might think that there is some sanity left in this world, and
the hierarchy for SXE/SXI looks like this:

    SimpleXMLElement implements IteratorAggregate
    // where SimpleXMLElement::getIterator() returns:
    SimpleXMLIterator implements Iterator

Of course, they would be wrong. The actual hierarchy is this:

    SimpleXMLElement implements Traversable
    SimpleXMLIterator extends SimpleXMLElement implements Iterator

The fact that SimpleXMLIterator extends SimpleXMLElement leaves me in a
tough spot, because it means SimpleXMLElement cannot be an
IteratorAggregate -- that would mean that SimpleXMLIterator implements both
IteratorAggregate and Iterator, which is not permissible.

It seems that it's also not possible to remove the "extends" without a
non-trivial backwards-compatibility break, because apparently writing
simplexml_load_string($str, 'SimpleXMLIterator') is a thing, which requires
SimpleXMLIterator to extend SimpleXMLElement (and possibly is the reason
why this was done in the first place.)

The only way out I see here is to lift the methods from SimpleXMLIterator
into SimpleXMLElement, make SimpleXMLElement implement Iterator itself, and
basically leave SimpleXMLIterator as a dummy extension of SimpleXMLElement.

Does that sound "reasonable"? Or rather, is there something more reasonable
that can be done?

Regards,
Nikita

Reply via email to