Hello internals, (this is my first email to this list, hopefully I'm doing ok.)
-------------------------------------------------------------------------------- Background / motivation: Currently in PHP we have an interface "Iterator", and a final class "Generator" (and others) that implement it. Using an iterator in foreach () is straightforward: foreach ($iterator as $key => $value) {..} However, if we want to iterate only a portion and then continue elsewhere at the position where we stopped, we need to do something like this: for ($iterator->rewind(); $iterator->valid(); $iterator->next()) { $value = $iterator->current(); [..] } This is unpleasantly verbose, and also adds performance overhead due to additional function calls. Also, manually writing an iterator is quite painful. I sometimes implement "readers" that can be used like this (*): // Gets a reader at position zero. $reader = $readerProvider->getReader(); while (FALSE !== $value = $reader->read()) { [..] } (*) Note that I am using FALSE as an equivalent for "end of data". Of course it would be nice if we had a dedicated constant for this, that does not constrain the range of possible values of the iterator. Such readers are much easier to write than iterators. However, there is no native support for foreach(), and for generator syntax with yield. Adapters from Iterator to Reader and vice versa are possible to write. However, such userland adapters add additional performance overhead: One call to ->read() will trigger one call to ->valid(), one to ->current(), one to ->next(). -------------------------------------------------------------------------------- Proposal: Establish a new interface in core, "Reader" or "ReaderInterface" (*). This interface has only one method, "->read()". The existing interface Iterator will remain unchanged. (*) I am open to other naming suggestions. In fact in my own projects I called this thing "StreamInterface", and distinguish between "ObjectStreamInterface", "RowStreamInterface" etc. Currently I think "Reader" might be more suitable. Let the final class "Generator", and possibly other native iterators, implement Reader in addition to Iterator. Optionally, add an interface "ReaderAggregate", or "ReaderAggregateInterface", or "ReaderProvider". This interface has only one method, "getReader()". Let ReaderAggregate extend Traversable, and add foreach() support. The key will simply be a counter. Open questions: - The naming of "Reader", "ReaderAggregate", "->read()". - Which return value to use for "end of data", so that FALSE would become a valid value. I currently don't see a better option than FALSE. -------------------------------------------------------------------------------- - Andreas Hennings (https://github.com/donquixote)