3

私はIteratorを調べて、なぜそれを使用すべきかを理解しましたが、得られなかったのは、 foreach を介してオブジェクトを反復する際に iterator クラスのメソッドがどのように呼び出されるかです。

PHPマニュアルページからコピーした以下の例を検討してください

class myIterator implements Iterator {
    private $position = 0;
    private $array = array(
        "firstelement",
        "secondelement",
        "lastelement",
    );  

    public function __construct() {
        $this->position = 0;
    }

    function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }

    function current() {
        var_dump(__METHOD__);
        return $this->array[$this->position];
    }

    function key() {
        var_dump(__METHOD__);
        return $this->position;
    }

    function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }

    function valid() {
        var_dump(__METHOD__);
        return isset($this->array[$this->position]);
    }
}

ここで、以下のように foreach を使用したときのことを理解したいと思います。

myIterator クラスのメソッドはどのように自動的に呼び出されますか?

$it = new myIterator;

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

ここでの魔法は何ですか?

4

2 に答える 2

1

それを「魔法」と呼びたいのであれば、Iteratorインターフェイスを実装するオブジェクトを使用して反復しようとすると、PHP には定義された動作があるということです。

ご存知かもしれませんが、インターフェースは、特定のメソッドが定義されることを示す、プログラマーとアプリケーションの間の単純な契約です。インターフェイスにメソッドを実装せずにクラスを定義すると、PHP は致命的なエラーをスローし、プログラムが終了します。これは、がインターフェイスforeachを実装するオブジェクトに遭遇したときに、そのオブジェクトが、、、および とIterable呼ばれるメソッドを持つことが保証されることを意味します。currentkeynextrewindvalid

valid を除いて、これらはすべて通常の配列にも存在するメソッドですが、オブジェクト メソッドではなく手続き型関数として存在します。(valid新しいアイテムを選択する関数はアイテムを返すため、配列には存在しません。したがってvalid、それらの関数に焼き付けられていると言えます。)これは、フードの下で、foreachループが多かれ少なかれ同じように機能することを示しています。配列とIterableオブジェクトの両方で。

オブジェクトを反復するプロセスは、質問でリンクしたマニュアルページIterableの例に示されているか、少なくとも暗示されていますが、混乱を招く可能性があることがわかります。プロセスの基本的な説明は次のとおりです。

一般に、foreachループは iterable のポインタを最初の位置にリセットします (ここで小さな I に注意してください -Iterableインターフェイスを実装する配列またはオブジェクトのいずれかを参照しています)。言い換えれば、テープを巻き戻すのと同じ方法で iterable を「巻き戻します」 - 若い世代では失われるかもしれない概念です。ご想像のとおり、これはrewindインターフェイスが必要とするメソッドです。

配列が巻き戻されると、foreachは現在選択されている要素を読み取ろうとします。現在の要素のデータは メソッドを使用してcurrent取得され、要素のキーはkeyメソッドを使用して取得されます。これらの項目は、foreachループで定義した変数に配置され、ループが反復を実行します。

ループの反復が完了すると、メソッドforeachを使用して次の要素を取得しようとします。next次に、最後の段落と同じ手順を実行してループを処理します。

オブジェクトでは、 andIterableを使用してデータを読み取る前に、ループがメソッドを呼び出します。このメソッドが、または PHP がそれと同等と見なす値 (0 や など)を返す場合、処理するものはこれ以上ないと見なし、ループを完全に終了し、プログラムは通常どおり続行します。currentkeyforeachvalidFALSENULLforeach

于 2013-01-05T13:18:22.743 に答える
0

魔法はありません。foreachオブジェクトが Iterator インターフェイスを実装しているかどうかを確認し、適切なメソッドを正しい順序で呼び出すだけです。

詳細については、http: //lxr.php.net/xref/PHP_5_4/Zend/zend_interfaces.cを参照してください。

于 2013-01-05T13:00:41.373 に答える