首頁  >  文章  >  後端開發  >  對php中IteratorIterator的理解(程式碼範例)

對php中IteratorIterator的理解(程式碼範例)

不言
不言轉載
2018-10-25 16:51:512498瀏覽

這篇文章帶給大家的內容是關於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 &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        reset($this->dates);
    }

    public function valid() 
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        if ($this->position >= count($this->dates)) {
            # code...
            return false;
        }
        return true;
    }

    public function current()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        return $this->dates[$this->position];
    }

    public function key()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        return $this->position;
    }

    public function next()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        ++$this->position;
    }}class OuterIterator extends \IteratorIterator{
    function rewind()
    {
        echo __METHOD__ .  &#39;<br>&#39;;
        return parent::rewind();
    }
    
    function valid()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::valid();
    }
    
    function current()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::current() . &#39;_suffix&#39;;
    }
    
    function key()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::key() ;
    }
    
    function next()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::next() ;
    }
    
    function getInnerIterator() 
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::getInnerIterator();
    }}$tmpArr = array(
    &#39;2018-10-01&#39;,
    &#39;2018-10-02&#39;,
    //&#39;2018-10-03&#39;,);$inner = new InnerIterator($tmpArr);$outer = new OuterIterator($inner);foreach ($outer as $key => $value) {
    # code...
    echo $key , &#39;=>&#39; , $value . &#39;<hr>&#39;;}

運行結果:

young\OuterIterator::rewind
call young\InnerIterator::rewind
call young\InnerIterator::valid
call young\InnerIterator::current
call young\InnerIterator::key
young\OuterIterator::valid
young\OuterIterator::current
young\OuterIterator::key
0=>2018-10-01_suffix
young\OuterIterator::next
call young\InnerIterator::next
call young\InnerIterator::valid
call young\InnerIterator::current
call young\InnerIterator::key
young\OuterIterator::valid
young\OuterIterator::current
young\OuterIterator::key
1=>2018-10-02_suffix
young\OuterIterator::next
call young\InnerIterator::next
call young\InnerIterator::valid
 young\OuterIterator::valid
 object(young\InnerIterator)#1 (2) { 
[“dates”:“young\InnerIterator”:private]=> array(2) { [0]=> 
string(10) “2018-10-01” [1]=> string(10) “2018-10-02” } 
[“position”:“young\InnerIterator”: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操作,但是這個操作在第二遍壓根就沒用~~~

以上是對php中IteratorIterator的理解(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除