SPL迭代器接口(二)—Iterator Interface

  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;
}

来源:慕课手记 https://www.imooc.com/article/17895

转载请注明出处:https://www.onexin.net/spl-iterator-interface/

相关文章:

1、SPL迭代器接口(六)—RecursiveIterator Interface
https://www.onexin.net/spl-recursiveiterator-interface/

2、SPL迭代器接口(五)—OuterIterator Interface
https://www.onexin.net/spl-outeriterator-interface/

3、SPL迭代器接口(四)—IteratorAggregate Interface
https://www.onexin.net/spl-iteratoraggregate-interface/

4、SPL迭代器接口(三)—SeekableIterator Interface
https://www.onexin.net/spl-seekableiterator-interface/

5、SPL迭代器接口(一)—Traversable Interface
https://www.onexin.net/spl-traversable-interface/

Leave a Reply