PHP迭代器类 [英] PHP Iterator classes

查看:109
本文介绍了PHP迭代器类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试图弄清楚在面向对象的PHP中使用Iterator类而不是标准数组的实际好处。

I'm trying to figure out what's the actual benefit of using Iterator classes in Object Oriented PHP over the standard array.

我打算升级我的框架通过将所有数组转换为对象,但我只是不了解系统完全OOP的实际需要。

I'm planning to upgrade my framework by converting all arrays to object, but I just don't understand the actual need apart from having the system being fully OOP.

我知道通过使用IteratorAggregate我可以创建:

I know that by the use of IteratorAggregate I can create:

class MyModel implements IteratorAggregate {

    public $records = array();

    public function __construct(array $records) {

        $this->records = $records;

    }

    public function getIterator() {

        return new ArrayIterator($this->records);

    }

}

然后简单像使用数组一样遍历它:

and then simply loop through it like using the array:

$mdlMy = new MyModel(array(
    array('first_name' => 'Mark', 'last_name' => 'Smith'),
    array('first_name' => 'John', 'last_name' => 'Simpson')
));



foreach($mdlMy as $row) {

    echo $row['first_name'];
    echo $row['last_name'];

}

有人可以用简单的术语解释这些的实际目的 - 也许有一些用例。

Could someone in simple terms explain the actual purpose of these - perhaps with some use case.

推荐答案

最短的答案



可扩展性和放大器;抽象。

Shortest Answer

Extensibility & abstraction.

只要你有 ArrayAccess 接口,你有一些不是数组但有数组接口的东西。你将如何穿越这些?您可以直接执行此操作,这是 Iterator 接口的来源。 Iterator 可能对某些类没有意义,或者由于单一责任原则,或者出于性能的考虑,这是你得到的地方 IteratorAggregate

As soon as you have the ArrayAccess interface, you've got things that aren't arrays but have an array interface. How will you traverse these? You could do it directly, which is where the Iterator interface comes from. Iterator might not make sense for some classes, either due to the single-responsibility principle, or for performance's sake, which is where you get IteratorAggregate.

SPL引入了一些数据结构。迭代器允许在 foreach 循环中遍历这些循环。如果没有迭代器,则需要将集合转换为数组,这可能是一项代价高昂的操作。

SPL introduced a number of data structures. Iterators allow these to be traversed in foreach loops. Without iterators, collections would need to be converted to arrays, a potentially costly operation.

第一次使用时会出现数据源(例如集合),这些数据源并非全部保存在数组中。示例(注意:有一些重叠):

The first use comes up with data sources (e.g. collections), which aren't all natively held in arrays. Examples (note: there is some overlap):



  • 文件系统

  • 前面提到的SPL数据结构

  • 网络通信

  • 数据库查询结果

  • 外部流程结果

  • 正在进行的计算(PHP 5.5为此引入了生成器 case)

  • trees
  • the file system
  • the previously mentioned SPL data structures
  • network communications
  • database query results
  • external process results
  • ongoing computation (PHP 5.5 introduces generators for this case)

任何非基于数组的集合通常都是迭代器或具有相应的迭代器。如果没有迭代器,上面的每一个都需要转换为或收集在一个数组中,这可能会导致繁重的时间和空间成本。如果您只有可用于迭代的数组,则在转换/收集完成之前,该过程无法继续。迭代器允许部分结果在可用时进行处理,并且只有部分集合在任何时间点都在内存中。

Any collection that isn't array-based typically either is an iterator or has a corresponding iterator. Without iterators, each of the above would need to be converted to or collected in an array, which might incur heavy time & space costs. If you only had arrays available for iteration, the process can't proceed until the conversion/collection finishes. Iterators allow for partial results to be processed as they become available, and for only portions of collections to be in memory at any point in time.

特别是在问题, UserEntityManager :: getAll()方法可以通过减少内存使用量从 Iterator 中受益。根据用于数据存储的内容, Iterator 将允许一次处理一些用户记录,而不是一次加载所有用户记录。

In particular case outlined in the question, the UserEntityManager::getAll() method could benefit from an Iterator by reducing memory usage. Depending on what is used for data storage, an Iterator will allow just some user records to be processed at a time, rather than loading all at once.

ArrayIterator ,< a href =http://php.net/DirectoryIterator =nofollow> DirectoryIterator ,SPL数据结构都是源代码的例子 - 迭代器(即它们迭代数据源)。

ArrayIterator, DirectoryIterator, and the SPL data structures are all examples of source-iterators (i.e. they iterate over a data source).

迭代器的另一个用途是 - 数据处理。处理迭代器包装其他迭代器,它允许迭代器组合。在PHP中,这些是 OuterIterator s ,有时候会有'名字中的IteratorIterator'。

Another use for iterators is in-place data processing. Processing iterators wrap other iterators, which allows for iterator composition. In PHP, these are the OuterIterators and sometimes have 'IteratorIterator' in their names.

您可能会问为什么不使用函数?答案是你可以,但迭代器组合(如功能组合)是另一种(强大的)工具,它允许不同类型的解决方案,有时可以实现更好的性能或清晰度。特别是,函数成为PHP中的一个瓶颈,因为它没有语言内并发性。函数必须在返回结果之前完成,这在时间和时间方面可能是昂贵的。空间,就像使用迭代的数组可能是昂贵的。浅。

You might ask "Why not just use functions?" The answer is that you could, but iterator composition (like function composition) is another (powerful) tool that allows for different types of solutions, sometimes achieving better performance or clarity. In particular, functions become a choke point in PHP, since it doesn't have in-language concurrency. Functions must finish before returning a result, which can be costly in terms of time & space, just as using arrays for iteration can be costly. Shallow.

通过从函数返回一个迭代器,阻塞点可以是侧向步进的,但是在每个迭代器之间放置一个函数调用。迭代器组合允许基于深度迭代器的计算,切断了中间人。

The choke-point could be side-stepped by returning an iterator from a function, but that places a function call in between each iterator. Iterator composition allows deep iterator-based computations, cutting out the middle-man.

对于用例,考虑使用来自多个源的数据的批处理系统,所有其中有不同的格式。适应迭代器可以规范化数据以进行处理,允许单个批处理器为所有提要服务。

As for use-cases, consider a batch processing system that consumes data from multiple feeds, all of which have different formats. An adapting iterator can normalize the data for processing, allowing a single batch processor to service all the feeds.

作为现实检查,在PHP中,您通常不会满员尽管PHP支持它,但迭代器风格不仅仅是你编写的全FP风格。您通常不会一次编写多个迭代器(正如您通常不会在具有函数组合的语言中编写多个函数一样),并且您不会创建多个迭代器而不是函数。

As a reality check, in PHP you typically don't go full iterator-style any more than you'd write full-FP style, though PHP supports it. You usually don't compose more than a few iterators at a time (just as you often don't compose more than a few functions at a time in languages with function composition), and you don't create numerous iterators instead of functions.

RecursiveIteratorIterator 是处理迭代器的一个例子;它使树线性化(简化树遍历)。

RecursiveIteratorIterator is an example of a processing iterator; it linearizes a tree (simplifying tree traversal).

迭代器组合允许样式更接近函数式编程。最基本的是,迭代器(大致)是一个序列。在FP中,最基本的操作是 fold (又名 reduce ),尽管其他人(尤其是 追加 / concat 过滤器 map )通常是本地实现的,而不是折叠以获得性能。 PHP支持迭代器上的一些序列操作(通常为 OuterIterator s);很多都丢失了,但很容易实现。

Iterator composition allows for a style closer to functional programming. At its most basic, an iterator is (roughly) a sequence. In FP, the most basic operation is fold (aka reduce), though others (especially append/concat, filter and map) are often implemented natively rather than in terms of fold for performance. PHP supports a few sequence operations on iterators (usually as OuterIterators); many are missing, but are easy to implement.


  • 追加 AppendIterator

  • cons :没什么,但很容易(虽然效率不高)通过创建一个迭代器来实现,该迭代器接受一个值,将其转换为单元素序列,以及 AppendIterator EmptyIterator 表示空序列。

  • 过滤器 CallbackFilterIterator

  • convolute (又名 zip ): MultipleIterator

  • slice LimitIterator

  • map - 没什么,但很容易实现

  • fold :没有。使用 foreach 循环并在变量中累积值可能比实现 fold 更清晰,但如果找到原因要做到这一点,它也很简单(虽然可能不是迭代器)。

  • flat-map :什么都没有。在追加 map 方面,可以相当容易地编写(虽然效率不高)。

  • 周期 InfiniteIterator

  • 展开生成器(通常只是迭代器的特例)。

  • memoization CachingIterator 。与功能结果的(FP语言)功能不同,序列操作。

  • append: AppendIterator
  • cons: nothing, but easily (though not efficiently) implemented by creating an iterator that takes a single value, converting it to a single-element sequence, along with AppendIterator. EmptyIterator represents the empty sequence.
  • filter: CallbackFilterIterator
  • convolute (aka zip): MultipleIterator
  • slice: LimitIterator
  • map - nothing, but easily implemented
  • fold: nothing. Using a foreach loop and accumulating a value in a variable is probably clearer than implementing fold, but if you find a reason to do so, it's also straightforward (though probably not as an iterator).
  • flat-map: nothing. Can be written fairly easily (though not efficiently) in terms of append and map.
  • cycle: InfiniteIterator
  • unfold: generators (which are, in general, just a special case of iterators).
  • memoization: CachingIterator. Not so much a sequence operation as an (FP language) feature for function results.

任何语言设计的一部分都在考虑语言是什么。如果将并发性添加到PHP中,那么使用迭代器(尤其是处理迭代器)的代码可以通过使迭代器本身并发而不进行更改来实现并发。

Part of any language design is considering what the language could be. If concurrency were ever added to PHP, code that uses iterators (especially processing-iterators) could be made concurrent without being changed by making the iterators themselves concurrent.

这篇关于PHP迭代器类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆