Heim  >  Artikel  >  Backend-Entwicklung  >  Verständnis von IteratorIterator in PHP (Codebeispiel)

Verständnis von IteratorIterator in PHP (Codebeispiel)

不言
不言nach vorne
2018-10-25 16:51:512499Durchsuche

Der Inhalt dieses Artikels befasst sich mit dem Verständnis von IteratorIterator in PHP (Codebeispiele). Ich hoffe, dass er für Sie hilfreich ist.

Persönliches Verständnis von IteratorIterator in PHP

Vor kurzem habe ich wieder angefangen, am Quellcode von Laravel herumzubasteln, nachdem ich ihn mehr als ein Jahr lang nicht verwendet habe . Jedes Mal, wenn ich es mir anschaue, werde ich damit beginnen. Ich habe in der Mittelschule viel gelernt. Wenn Sie etwas nicht verstehen, schauen Sie einfach im Handbuch nach. Ich habe den Teil gesehen, der die Konfigurationsdatei (config/*.php) lädt. Die spl-Klassenbibliothek und die Schnittstelle werden im Code häufig verwendet. Es gibt zu wenig Informationen im Internet Ich bin nicht sehr schlau. Ich habe es mehrmals getan. Genius hat einige Hinweise, und das Folgende ist mein persönliches Verständnis davon.

Einführung in IteratorIterator

IteratorIterator ist ein Iterator-Wrapper und natürlich auch selbst ein Iterator. Es muss (vorausgesetzt, es heißt Outer) eine Iteratorinstanz übergeben, die den Traversable-Schnittstellentyp implementiert (vorausgesetzt, es heißt Inner), wenn es instanziiert wird. Natürlich können Sie diesen eingehenden Iteratorparameter Inner über die Methode getInnerIterator von Outer erhalten. Sie können den internen Iterator Inner über die Methoden rewind(), next(), valid(), current() und key() von Outer verarbeiten.

Wichtige Punkte, die es zu verstehen gilt

  1. Beim Durchlaufen von Outer werden Outer einfach rewind(), next(), valid(), current() und key() durchlaufen. Jeder Aufruf leitet an den inneren Iterator Inner weiter.

  2. Outer kann die durch Weiterleitung zurückgegebenen Ergebnisse umschließen, dies hat jedoch keine Auswirkungen auf Inner.

Codedemonstration

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

Laufergebnisse:

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

Ergebnisanalyse

Jedes Mal Outer The Die Iteration ruft zunächst ihre eigene Methode auf und leitet sie dann an Inner weiter.
Der Rückgabewert der internen Methode von Outer basiert auf dem Rückgabewert von Inner relativ zur Methode.
Sie können den Rückgabewert von Inner in der Methode innerhalb von Outer logisch verarbeiten.
Wenn die Gültigkeit von Inner false zurückgibt, stoppt auch das äußere Outer die Iteration.
Eine Änderung des Rückgabewerts durch die Methode in Outer hat keine Auswirkungen auf Inner.
Die Methode in Outer führt die getInnerIterator-Methode während des Iterationsprozesses nicht aus. Es handelt sich lediglich um eine aufrufende Schnittstelle zum Abrufen der Inner-Methode.

Eine kleine Ergänzung

Ich habe diese Art von Verwirrung schon einmal gesehen, als ich online nach Informationen gesucht habe

//假如这里还是使用了上面的两个类代码
<?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  问题二

Hier gibt es zwei Fragen,

  1. Frage eins, warum Strom keinen Wert hat und gültig ist, ist falsch

  2. Frage zwei, warum nach Weiter und Zurückspulen Strom der zweite Wert ist

Aus den obigen Ausführungsergebnissen können wir ersehen, dass $outer keinen Rücklauf ausführt und $inner auch nicht, sodass valid false zurückgibt, current null ist und _suffix nur von selbst gespleißt wird.
Das zweite Problem ist auch sehr seltsam. Solange sich der Zeiger von $inner nach vorne bewegt, kann das Positionsattribut von $inner nach dem ersten nächsten nicht zurückgehen. Selbst wenn Sie zurückspulen, ist die Position immer noch 1, was etwas verwirrend ist. . .
Wenn Sie also den $outer-Traversal-Vorgang ausführen, wird beim zweiten Mal kein Wert ausgegeben. Selbst wenn der Rückspulvorgang zum zweiten Mal ausgeführt wird, ist dieser Vorgang beim zweiten Mal nutzlos~~~

Das obige ist der detaillierte Inhalt vonVerständnis von IteratorIterator in PHP (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen