开发者

PHP - Reasons to use Iterators?

I was perusing the manual today and noticed the various iterators. To me, it seems like they are all开发者_运维技巧 somewhat pointless; I don't see a reason to use them unless you prefer their syntax, or don't know how to write a recursive function. Are there any reasons to use built-in iterators in PHP over just writing a loop or making a recursive method?

I'm only looking for factual responses, not subjective preferences (ie: I don't care if you think it's more "readable" or "more object-oriented", I want to know if they're faster, offer functionality that can't be achieved when rolling your own, etc.).


The main advantage of iterators is that they abstract the concept of iteration. This means that any data providers can be used through the same interface. And that's exactly where you can take advantage of them:

  • Laziness
  • Reduced memory usage
  • Composition

Laziness

With data providers, the data is only fetched when you actually need it (eg. when you iterate).

Reduced memory usage

Iterators encourage you to process data iteratively, instead of buffering it in memory. While it is possible to do this without iterators, the abstractions they provide hide the implementation which makes them really easy to use.

Composition

What mario said.


Juozas Kaziukėnas recently wrote a blog post of how he could use iterators to emulate lazy evaluation in PHP. It goes into detail about some of the things I've mentioned.


I believe the main reason is versatility. They don't make things more readable and you can accomplish most of what the spl iterators do with a simple foreach.

But iterators can serve as sort of a compacted loop or loop source that you can pass around. You can have more diverse data sources than just a list/array. And the real advantage is that you can wrap or stack them for aggregation.

The naming is somewhat unobvious, but I guess you could use the AppendIterator to for example combine a static list of filenames and the result of a DirectoryIterator. Or otherwise wrap that in a LimitIterator instead of hardwiring that into a for condition. All of these are pretty basic features and can be done manually in a foreach. But at least RegexIterator and FilterIterator seem suitable to reduce some complexity.

But in the end it's really a stylistic choice. It would make most sense if you have custom objects which traverse something (for example a VFS object which can either point to real files or database entries). But even then you could just iterator_to_array convert such a list, and use a normal foreach-over-array.

The only case were it is really imperative to prefer iterators were if the data source is unlimited in size. Unfolded arrays for use in a foreach can consume more memory than an iterator which can retrieve element by element.


The question can have very wide variety of answers, but proper answers probably can be summarized as: Iterator can be used for iterating anything more complex than simple array.

One example is some kind of ORM or query builder. Assume we have one - using it could look like that:

$friends = new Model_Friend();
$friends = $people->where('age','>',30)->where('gender','=','female');
foreach ($friends as $friend) {
    echo $friend->name;
}


One simple example: Implementing an object that can be accessed and traversed like an array. SimpleXML is a nice example of the powerful behavior that can be achieved with this.

To accomplish this you could implement the Iterator interface which defines the methods public current(), public key(), public next(), public rewind() and public valid().

Or you can simply implement the alternative IteratorAggregate interface which defines one method public getIterator() which simply returns an Iterator for the internal data you want to expose.

Be sure to check out the examples of the above Interfaces and you'll see the advantage.


Iterators are just as fast as anything else, but with an easier interface and perhaps more verbage to wrap it in. However, the main advantage is not what you may need right now, but how you can extend them to deal with your future problems (and they will come!), and that is what we old boys call "saving your future ass". :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜