PHP反復モードのIteratorとIteratorAggregate

4792 ワード

反復モードを使用してすべてのオブジェクトを巡回する場合は、Transversableインタフェースを実装する必要があります.しかし、Traversableは内部のクラスであり、c言語で記述されたクラスだけがTraversable実装を実現することができる.カスタムクラスで実装すると、エラーが発生します.では、オブジェクトの遍歴を実現するには、
IteratorまたはIteratorAggregate接続
ポートはTransversableインタフェースを実現します.
まず、Iteratorインタフェースについてお話しします.これはc言語で定義されており、抽象的な方法なので、インタフェースを実現する際に、これらの方法を定義する必要があります.コードは以下の通りです.
    Iterator extends Traversable {
    /*    */
    abstract public mixed current ( void )
    abstract public scalar key ( void )
    abstract public void next ( void )
    abstract public void rewind ( void )
    abstract public boolean valid ( void )
   }

次に、PHPでインタフェースIteratorを実装します.コードは以下の通りです.
 
    //        Iterator
class myIterator implements Iterator {
    private $position = 0;
    private $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );  

    public function __construct() {
        $this->position = 0;
    }
    //  rewind()-               
    function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }
    //  current()-      
    function current() {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }
    //    key()-       
    function key() {
        var_dump(__METHOD__);
        return $this->position;
    }
    //  next()-                   
    function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }
    //  valid()-          ,     next() rewind()         
    function valid() {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
    }
}

$it = new myIterator;

foreach($it as $key => $value) {
    var_dump($key, $value);
    echo "
"; }

コードの実行結果は次のとおりです.
なぜforeach()を利用すればクラスの属性をループ印刷できるのか分からないかもしれませんが、プログラムの実行順序は私のコメントを見て、もう一度注意してください.
「valid()の定義-現在の要素が存在するかどうかを決定し、next()メソッドとrewind()メソッドの後で呼び出す必要があります」.
string(18)「myIterator::rewind」-------プログラムは、まずrewind()関数を呼び出し、配列ポインタを配列先頭位置に移動する
string(17)「myIterator::valid」--------次にvalid()の現在の要素が存在するかどうかを呼び出します.この関数はrewind()とnext()関数に続くたびに呼び出されます.
string(19)「myIterator::current」--------current()を呼び出して現在の値を取得
string(15)「myIterator::key」--------key()を呼び出して現在位置のキー値を取得
int(0)
string(12) "firstelement"
string(16)「myIterator::next」--------前のステップで現在位置を取得するには、必ずnext()を呼び出し、次の位置のポインタ、すなわちポインタを下に移動する
string(17)「myIterator::valid」--------現在の要素が存在するか否かを判断する
string(19)「myIterator::current」--------存在する場合、現在の要素を取得
string(15)「myIterator::key」--------現在のキー値を取得し、次のポインタを前に移動する
int(1)
string(13) "secondelement"
string(16)「myIterator::next」------ポインタは次の要素を指します
string(17)「myIterator::valid」------現在の要素が存在するか否かを判断
string(19)「myIterator::current」------要素が存在し、現在の要素を取得
string(15)「myIterator::key」------現在のキー値を取得
int(2)
string(11) "lastelement"
string(16)「myIterator::next」----------ポインタが次の位置を指す
string(17)「myIterator::valid」------現在位置に値があるかどうかを判断します.取得値がある場合は、取得値がない場合はループを終了します.
二、IteratorAggregateインタフェース(Iteratorインタフェースが実装を要求する5つの方法を他のクラス(例えばArrayIterator)に委任して実装する)
(1)ArrayIteratorインタフェース:PHP配列から反復器を作成できます.上記ではIteratorインタフェースを実装することによって反復器を実装したが,ArrayIteratorは直接スキップして同様の機能を実現できる.
(2)ArrayIterator反復器がIteratorAggregateクラスと一緒に使用される場合、Iterator作成メソッドの作業は直接免除されるので、IteratorAggregateクラスのメソッドgetIteratorを実装する場合は、ArrayIteratorインタフェースを返すとよい.
(3)IteratorAggregateのc言語実装コード:抽象メソッドgetIteratorを定義するので,インタフェースを実装する際には,そのメソッドを定義する必要がある.
             IteratorAggregate extends Traversable { 
                   /*    */
                 abstract public Traversable getIterator ( void )
   
                }
//      :
class myData implements IteratorAggregate {
    public $property1 = "Public property one";
    public $property2 = "Public property two";
    public $property3 = "Public property three";

    public function __construct() {
        $this->property4 = "last property";
    }
    //    ----getIterator()---    Iterator    
    public function getIterator() {
		//ArrayIterator()        Iterator  
        return new ArrayIterator($this);
    }
}

$obj = new myData();

foreach($obj as $key => $value) {
    var_dump($key, $value);
    echo "
"; }

次のように動作します.
string(9) "property1"
string(19) "Public property one"
string(9) "property2"
string(19) "Public property two"
string(9) "property3"
string(21) "Public property three"
string(9) "property4"
string(13) "last property"
/******************************************
みんなを助けて、あなた達の問題を解決することを望みます