For the complete documentation index, see llms.txt. This page is also available as Markdown.

预定义接口(Predefined Interfaces)

  1. Traversable

  2. Iterator

  3. IteratorAggregate(聚合式迭代器)接口

  4. Generator 生成器

  5. ArrayAccess

  6. Serializable

  7. Closure

IteratorAggregate(聚合式迭代器)接口

接口摘要

IteratorAggregate extends Traversable {
/* 方法 */
abstract public Traversable getIterator ( void )
}

个接口实现了一个功能——创建外部迭代器,具体怎么理解呢,当我们使用foreach对对象进行便遍历的时候,如果没有继承IteratorAggregate接口,遍历的是对象中所有的public属性(只能是public $var这种形式)。要是继承了IteratorAggregate,会使用类中实现的getIterator方法返回的对象,这里要注意返回的一定要是一个Traversable对象或者扩展自Traversable的对象,否则会抛出异常

示例:

ArrayIterator 对数组进行了Iterator封装

class My{
 private $_data = [
 'a' => '燕睿涛',
 'b' => 'yanruitao',
 'c' => 'LULU',
 ];

 public function getIterator()
 {
   return new ArrayIterator($this->_data);
 }
}
$obj = new My;
foreach ($obj as $key => $value) {
 echo "$key => $value\n";
}
//输出结果为空

改造

结果:

示例:

Countable 的目的是能够使用php count函数来统计日志的行数

Iterator 迭代器需要实现current() key() next() rewind() valid()方法

foreach 之前,先rewind() ,将遍历的指针重置到遍历的开头,调用next() 将指针移动到下一个位置,current() 则可以获得当前指针指向数据,每次循环都会调用valid()方法,如果返回false,则证明遍历结束

a.log

思考:为什么不用 file() 函数读到数组里面再遍历?

有可能会出现一下错误(内存不够用):

解决办法:

用生成器!

生成器(Generator)

  • 生成器提供了一种更简单的可实现 Iterator 同样功能的方法。

  • 你可以通过生成器逐条产生(yield)供 foreach 遍历的数据,而且不需要事先在内存中建立整个数组。

  • 生成器像一个函数,但是使用关键词 yield 返回数据。

Generator 是 Traversable 的子类

示例:

进一步key=>value形式

IteratorAggregate 与 yield 的结合示例

getIterator 需要返回一个Traversable 对象, 生成器yield 就是一个Traversable的对象的子类

总结

  • 实现了 Traversable 的对象都可以通过 foreach 实现遍历;

  • 生成器函数实现 foreach 更简单,适用于简单的数据和逻辑;

  • Iterator 实现 foreach 可定制性更高,适用于较复杂的逻辑;

  • IteratorAggregate 可返回一个外部迭代器,可对数据本身及相关逻辑做更统一的封装。

资料

PHP之预定义接口详解

Last updated