2017-09-29 5 views
5

私は初心者ですし、php.netから学びます。このインタフェースを実装するクラスは、foreach構文で使用することができ、のIteratorAggregateやIteratorを実装する必要はありませんPHPのforeachループでIterateAggregateまたはIteratorを使用できますか?

内部(ビルトイン):そのページ上のノートhttp://php.net/manual/en/class.traversable.phpは)と述べています

注:とは何ですか?つまり、私はforeachループの内部にあるIteratorAggregateまたはIteratorをクラスなしで使用できますか、私は間違っている可能性があります。誰がこれは何を言うことができますは言う??

答えて

2

IteratorAggregateあなたがforeachを使用してオブジェクトカスタムクラスをトラバースすることを可能にする外部イテレータを作成するインタフェースです:

class FooBarClass implements IteratorAggregate 
{ 
    public $property = "Nothing to see"; 

    public function __construct() 
    { 
    } 

    public function getIterator() 
    { 
     return new ArrayIterator($this); 
    } 
} 

$obj = new FooBar; 

foreach($obj as $key => $value) { 
    print(var_dump($key, $value) . "\n"); 
} 

Iteratorは、外部イテレータのためインタフェースですクラスやオブジェクトを内部的に繰り返し処理することができます:

class myIterator implements Iterator 
{ 
    private $position = 0; 
    private $array = array('one', 'two', 'three'); 

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

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

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

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

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

それにもかかわらず、IteratorAggregateと同じ方法でオブジェクトをトラバースできます。

違いは、IteratorAggregateはイテレータより実装が容易であり、一般的に高速です。欠点は、トラバーサルのためだけであり、foreachトラバーサルの間に呼び出されないので、next()、key()などのメソッドを提供しないことです。

Iterator(またはそれ以上の具体的なOuterIteratorまたは(簡単に)IteratorIterator)は、あなたのオブジェクトを介して反復を超える非常に細かい制御を持っているし、次の(上のカスタム例外を追加することができますが)、キー()またはPREV()

参考にしているメモは、PHPの内部クラス(C言語で書かれています)のいくつかがこのインターフェイスを直接実装することを意味しています。 Traversableを実装する必要のあるユーザランドクラスは、IteratorAggregateまたはIteratorを実装するか、Traversableの別の下位クラスを実装する必要があります。 Pro PHP by Kevin McArthur pを参照してください。 143f。

Traversableインターフェイス自体は、インスタンス化できない抽象的なベースインターフェイス(インターフェイスの概要に示されているメソッドはありません)です。ただし、foreachを使用してクラスが移動可能かどうかを確認するために使用できます。

Traversable { 
} 

混乱の一部のオブジェクトと配列はない「Traversableの」を実装、まだforeachのことでcan be traversed、しかし、あなたはinstanceof小切手またはtype hintを使用してforeachの互換性のためできないチェックんです。

$myarray = array('one', 'two', 'three'); 
$myobj = (object)$myarray; 

if (!($myarray instanceof \Traversable)) { 
    print "myarray is NOT Traversable"; 
} 
if (!($myobj instanceof \Traversable)) { 
    print "myobj is NOT Traversable"; 
} 

前述のとおり、すべてのオブジェクトをforeachでトラバースすることができますが、パブリックプロパティにアクセスするだけで済みます。 Object Iteration上のPHPマニュアルから引用:それは例えば、で、項目のリストを 反復するforeachの 声明可能ですので

PHP 5はオブジェクトを定義するための方法を提供します。既定では、表示されるすべてのプロパティは、反復の に使用されます。

あなたがプライベートと保護値を持つオブジェクトをカプセル化し、それをアクセスするためのgetterおよびsetterメソッドを記述するのであれば、あなたはのIteratorAggregateやIteratorを実装するクラスを好きで、foreach文では、これらの値にアクセスできるようにロジックを書くこと必要に応じて。手短に言えば、(IteratorまたはIteratorAggregateを介して)Traversableインターフェイスを実装するオブジェクトは、「配列のように動作します」。ただし、オブジェクトを反復処理する必要はありません。しかし、それらの動作を変更したい場合は、Iteratorを実装する必要があります。組み込みクラスにも同じロジックが適用されます。

+0

あなたの回答は、私が尋ねた質問の**注**とはまったく異なります。 ** note **を簡単な言葉で説明してください。それは質問で尋ねられますか? –

+0

私は助けてくれてありがとう。私に多くのことを強調したことの1つは、そのメモの中の** foreach **という言葉です。組み込みの内部クラスが** Traversable **インタフェースを実装しているかどうかは、** IteratorAggregate **または** Iterator **インタフェースを実装せずに**直接** ** foreach **ループでTraversable **を使用することを意味しますか?または私は間違っているかもしれないので、教えてください。 –

+0

** ** foreach **という言葉は私を混乱させ、** ** note **の** foreach **のシナリオは何か分かりません。 –

関連する問題