对php中IteratorIterator的理解(代码示例)

如果下载的源码需要作者授权,请更换源码。本站免费分享资源不会增加授权

本篇文章给大家带来的内容是关于php中IteratorIterator的理解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

php之IteratorIterator个人理解

最近有重新开始捣鼓laravel的源码了,一年多没用实在是忘的差不多了,每次看都会从中学到很多,不懂就赶紧查手册。看到加载配置文件的部分(config/*.php),代码中大量使用spl类库和接口,今天就来扯一下IteratorIterator类,网上资料太少了,加上本人也不是怎么聪明,搞了好几天才有点眉目,以下是对它的个人理解。

IteratorIterator简介

IteratorIterator是一个迭代器包装器,当然它本身也是迭代器。它(假定它叫Outer)在实例化时必须传入一个实现了Traversable接口类型的迭代器实例(假定它叫Inner),当然你可以通过Outer的getInnerIterator方法获取到这个传入的迭代器参数Inner。你可以通过Outer的rewind(),next(),valid(),current()和key()方法对内部迭代器Inner进行处理。

重点理解

  1. 在遍历Outer的过程中,Outer只是将rewind(),next(),valid(),current()和key()的任何调用转发给内部迭代器Inner。

  2. Outer可以对转发返回的结果进行包装,但这并不会对Inner产生任何影响。

代码演示

<?php namespace young;class InnerIterator implements Iterator{     private $dates;     private $position;      public function __construct($dates = [])     {         $this->dates    = $dates;         $this->position = 0;     }      public function rewind()     {         echo 'call ' . __METHOD__ . '<br>';         reset($this->dates);     }      public function valid()      {         echo 'call ' . __METHOD__ . '<br>';         if ($this->position >= count($this->dates)) {             # code...             return false;         }         return true;     }      public function current()     {         echo 'call ' . __METHOD__ . '<br>';         return $this->dates[$this->position];     }      public function key()     {         echo 'call ' . __METHOD__ . '<br>';         return $this->position;     }      public function next()     {         echo 'call ' . __METHOD__ . '<br>';         ++$this->position;     }}class OuterIterator extends IteratorIterator{     function rewind()     {         echo __METHOD__ .  '<br>';         return parent::rewind();     }          function valid()     {         echo __METHOD__ . '<br>';         return parent::valid();     }          function current()     {         echo __METHOD__ . '<br>';         return parent::current() . '_suffix';     }          function key()     {         echo __METHOD__ . '<br>';         return parent::key() ;     }          function next()     {         echo __METHOD__ . '<br>';         return parent::next() ;     }          function getInnerIterator()      {         echo __METHOD__ . '<br>';         return parent::getInnerIterator();     }}$tmpArr = array(     '2018-10-01',     '2018-10-02',     //'2018-10-03',);$inner = new InnerIterator($tmpArr);$outer = new OuterIterator($inner);foreach ($outer as $key => $value) {     # code...     echo $key , '=>' , $value . '<hr>';}

运行结果:

youngOuterIterator::rewind
call youngInnerIterator::rewind call youngInnerIterator::valid call youngInnerIterator::current call youngInnerIterator::key
youngOuterIterator::valid youngOuterIterator::current youngOuterIterator::key 0=>2018-10-01_suffix youngOuterIterator::next
call youngInnerIterator::next call youngInnerIterator::valid call youngInnerIterator::current call youngInnerIterator::key
youngOuterIterator::valid youngOuterIterator::current youngOuterIterator::key 1=>2018-10-02_suffix youngOuterIterator::next
call youngInnerIterator::next call youngInnerIterator::valid

 youngOuterIterator::valid  object(youngInnerIterator)#1 (2) {  [“dates”:“youngInnerIterator”:private]=> array(2) { [0]=>  string(10) “2018-10-01” [1]=> string(10) “2018-10-02” }  [“position”:“youngInnerIterator”:private]=> int(2) }

结果分析

Outer的每次迭代会先调用自己的方法,然后转发给Inner。
Outer内部方法的返回值都是基于Inner的相对于方法的返回。
你可以在Outer内方法对Inner的返回值做逻辑处理。
当Inner的valid返回false的时候,外层的Outer也将停止迭代。
Outer内的方法对返回值的修改并不会影响Inner。
Outer内的方法在迭代过程中并不会执行getInnerIterator方法,它只是一个获取Inner方法的调用接口。

一点补充

之前在网上翻阅资料时会看到这样的疑惑

//假如这里还是使用了上面的两个类代码 <?php namespace young; class InnerIterator implements Iterator {     //code 这里的代码假如和上面的一样 } class OuterIterator extends IteratorIterator {     //code 这里的代码假如和上面的一样 } $outer->valid();           //false $outer->current();         // _suffix  问题一 $outer->rewind();     $outer->valid();            //true $outer->current();         //2018-10-01_suffix $outer->next() $outer->rewind(); $outer->current();         //2018-10-02_suffix  问题二

这里有两个问题,

  1. 问题一,为什么当前current没值,valid为false

  2. 问题二,问什么next后rewind之后,current是第二个值

从上面的运行结果可知,$outer不执行rewind,$inner也不会执行,所以valid返回false,current为null,_suffix只是自己拼接上的。
第二个问题也是很奇怪的,也是刚刚发现的,$inner的指针只要前进了,就回不去了,也就是说 $inner的position属性在第一次next之后变成1了,即使你rewind,position还是1,这个有点蒙蔽啊。。。
所以如果你进行了$outer的遍历操作,第二遍是没值输出的,即使第二遍也执行了rewind操作,但是这个操作在第二遍压根就没用~~~

本文由(壳先生)整理自网络,如转载请注明出处:https://www.mrshell.com;
本站发布的内容若侵犯到您的权益,请邮件联系 i@mrshell.com 删除,我们将及时处理!
===========================================================================

1. 本站大部分下载资源收集于网络,不保证其完整性以及安全性,请下载后自行测试。
2. 本站资源仅供学习和交流使用,版权归资源原作者所有,请在下载后24小时之内自觉删除。
3. 不得使用于非法商业用途,商用请支持正版!不得违反国家法律,否则后果自负!
4. 若作商业用途,请购买正版,由于未及时购买和付费发生的侵权行为,与本站无关。
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!

=================================================================

壳先生 » 对php中IteratorIterator的理解(代码示例)

发表评论

提供最优质的资源集合

立即查看 了解详情