Iterator Interface:直接继承自Traversable接口的两个基本迭代器接口之一。
Iterator接口允许一个类实现一个基本的迭代功能,从而使它可以被循环访问,根据键值访问和回滚。
示例代码:
<?php
//自定义数组容器实现迭代器接口
class MyIterator implements Iterator
{
protected $data = array('唐朝','宋朝','元朝'); //存放数据
protected $index ; //存放当前指针
public function current()
{
return $this->data[$this->index];
}
//指针+1
public function next()
{
$this->index ++;
}
//验证指针是否越界
public function valid()
{
return $this->index < count($this->data);
}
//重置指针
public function rewind()
{
$this->index = 0;
}
//返回当前指针
public function key()
{
return $this->index;
}
}
//实例化一个迭代器
$container = new MyIterator();
//遍历数组容器
foreach($container as $key =>$dynasty){
echo '如果有时光机,我想去'.$dynasty.PHP_EOL;
}
运行结果:
为什么实现Iterator接口就可以把一个MyIterator
对象当成数组一样进行遍历呢?我们在代码中的每个方法中加入一句。
echo __METHOD__,PHP_EOL;
<?php
//自定义数组容器实现迭代器接口
class MyIterator implements Iterator
{
protected $data = array('唐朝','宋朝','元朝'); //存放数据
protected $index ; //存放当前指针
//返回当前指针指向数据
public function current()
{
echo __METHOD__,PHP_EOL;
return $this->data[$this->index];
}
//指针+1
public function next()
{
echo __METHOD__,PHP_EOL;
$this->index ++;
}
//验证指针是否越界
public function valid()
{
echo __METHOD__,PHP_EOL;
return $this->index < count($this->data);
}
//重置指针
public function rewind()
{
echo __METHOD__,PHP_EOL;
$this->index = 0;
}
//返回当前指针
public function key()
{
echo __METHOD__,PHP_EOL;
return $this->index;
}
}
//实例化一个迭代器
$container = new MyIterator();
//遍历数组容器
foreach($container as $key => $dynasty){
echo '如果有时光机,我想去'.$dynasty.PHP_EOL;
}
再次运行:
这个时候我们可以发现foreach
语句的本质,实际上是PHP帮我们自动顺序调用了迭代器对象的rewind->valid->currrent->key->next->valid->..........
从而实现把类中的属性数组迭代出来。
具体流程图:
(key方法和current方法顺序倒了,以我们的测试为主,应该是current方法先调用)
如果我们使用两次foreach呢?
//遍历数组容器
foreach($container as $key =>$dynasty){
echo '如果有时光机,我想去'.$dynasty.PHP_EOL;
}
echo '------第二次使用迭代器-----'.PHP_EOL;
foreach($container as $key =>$dynasty){
echo '如果有时光机,我想去'.$dynasty.PHP_EOL;
}
再次运行:
注意foreach中不能使用break;
//遍历数组容器
foreach($container as $key =>$dynasty){
$key==1 && break;
echo '如果有时光机,我想去'.$dynasty.PHP_EOL;
}