ループしたいものは実装する必要がありますTraversable
。Traversable
ただし、直接実装することはできません。そのサブタイプの 1 つを実装する必要があります。どのように行うかは、オブジェクトがどのように使用されるかによって異なります。
必要に応じて、実装することもできますIterator
。あなたのタイプがすでに前方のみのリストであることを意図している場合、それは十分に機能します。イテレータを作成することにした場合、実装するメソッドが 5 つあります。
current
、現在の場所の値を取得します。
key
、現在の場所のキーを取得します。
next
、次の場所に進みます。
rewind
、現在の場所を最初にリセットします。と
valid
false
、反復が反復されているもののリストの最後から外れている場合に返されます。
PHP は、反復の過程でこれらのメソッドを呼び出します。具体的には、次のようなコードがあるとします。
foreach ($it as $key => $value) {
doStuffWith($key, $value);
}
これは、以下とほぼ同等です。
for ($it->rewind(); $it->valid(); $it->next()) {
$value = $it->current();
$key = $it->key(); // only if the foreach has a `$key =>`
doStuffWith($key, $value);
}
implements Iterator
基本的には、大まかにその順序で呼び出されるメソッドに適切に応答するタイプを構築するだけです。理想的には、その間に何かが発生する可能性もあるはずです...しかし、参照を渡している場合を除き、通常は問題になりません。
カスタム反復が必要ない場合は、代わりに を実装しIteratorAggregate
、必要なことができる場合は既存の反復子型を返すことができます。(たとえば、内部配列のループを許可したい場合はArrayIterator
、そのジョブ用の が既に用意されています。自分で作成する必要はありません。) の場合は、トラバース可能なものを返すIteratorAggregate
を実装するだけで済みます。これは、組み込みの SPL iteratorsgetIterator
のいずれかで既にトラバースできるものがある場合、または配列などに簡単に縮小できるものがある場合に適したソリューションです。
上記の同じループが IteratorAggregate で呼び出された場合、次のようになります。
foreach ($it->getIterator() as $key => $value) {
doStuffWith($key, $value);
}
getIterator()
の実装かIterator
、配列のようなプリミティブなトラバース可能なものを返す必要があります。
Java スタイルの反復子については、その場所を記憶してコレクションをループできる Iterator サブタイプを構築し、コレクションに実装IteratorAggregate
して反復子型のインスタンスを返すことができます。