Iterator 接口


首先要从foreach说起,我们都知道对象,数组和对象可以被foreach语法遍历,数字和字符串却不行。
其实除了数组和对象之外PHP内部还提供了一个 Iterator 接口,实现了Iterator接口的对象,也是可以被foreach语句遍历,当然跟普通对象的遍历就很不一样了。 以下面的代码为例:
class Number implements Iterator{   protected $key;   protected $val;   protected $count;   public function __construct(int $count){     $this->count = $count;   }   public function rewind(){     $this->key = 0;     $this->val = 0;   }   public function next(){   $this->key += 1;   $this->val += 2;   }   public function current(){     return $this->val;   }   public function key(){   return $this->key + 1;   }   public function valid(){     return $this->key < $this->count;   } } foreach (new Number(5) as $key => $value){   echo "{$key} - {$value}\n"; } 

这个例子将输出

1 - 0
2 - 2
3 - 4
4 - 6
5 - 8

关于上面的number对象,被遍历的过程。如果是初学者,可能会出现有点懵的情况。为了深入的了解Number对象被遍历的时候内部是怎么工作的,我将代码改了一下,将接口内的每个方法都尽心输出,借此来窥探一下遍历时对象内部方法的的执行情况。

 

class Number implements Iterator{ protected $i = 1; protected $key; protected $val; protected $count; public function __construct(int $count){ $this->count = $count; echo "第{$this->i}步:对象初始化.\n"; $this->i++; } public function rewind(){ $this->key = 0; $this->val = 0; echo "第{$this->i}步:rewind()被调用.\n"; $this->i++; } public function next(){ $this->key += 1; $this->val += 2; echo "第{$this->i}步:next()被调用.\n"; $this->i++; } public function current(){ echo "第{$this->i}步:current()被调用.\n"; $this->i++; return $this->val; } public function key(){ echo "第{$this->i}步:key()被调用.\n"; $this->i++; return $this->key; } public function valid(){ echo "第{$this->i}步:valid()被调用.\n"; $this->i++; return $this->key < $this->count; } } $number = new Number(5); echo "start...\n"; foreach ($number as $key => $value){ echo "{$key} - {$value}\n"; } echo "...end...\n";

 

以上代码输出如下

 

第1步:对象初始化. start... 第2步:rewind()被调用. 第3步:valid()被调用. 第4步:current()被调用. 第5步:key()被调用.
0 - 0 第6步:next()被调用. 第7步:valid()被调用. 第8步:current()被调用. 第9步:key()被调用.
1 - 2 第10步:next()被调用. 第11步:valid()被调用. 第12步:current()被调用. 第13步:key()被调用.
2 - 4 第14步:next()被调用. 第15步:valid()被调用. 第16步:current()被调用. 第17步:key()被调用.
3 - 6 第18步:next()被调用. 第19步:valid()被调用. 第20步:current()被调用. 第21步:key()被调用.
4 - 8 第22步:next()被调用. 第23步:valid()被调用.
...end...

 

看到这里,我相信大家对Iterator接口已经有一定认识了。

会发现当对象被foreach的时候,内部的valid,current,key方法会依次被调用,其返回值便是foreach语句的key和value。

循环的终止条件则根据valid方法的返回而定。

如果返回的是true则继续循环,如果是false则终止整个循环,结束遍历。

当一次循环体结束之后,将调用next进行下一次的循环直到valid返回false。

而rewind方法则是在整个循环开始前被调用,这样保证了我们多次遍历得到的结果都是一致的。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM