注: ジェネレーターは PHP5.5 以降でのみサポートされています。
ジェネレーターは、パフォーマンスのオーバーヘッドや Iterator インターフェイスを使用したクラスの実装の複雑さを伴うことなく、単純なオブジェクトの反復を実装する簡単な方法を提供します。
ジェネレーターを使用すると、メモリ内に配列を作成せずに、foreach ブロックにコードを記述してデータのセットを反復処理できます。これにより、メモリの制限に達したり、かなりの処理時間がかかってしまいます。代わりに、通常のカスタム関数と同じようにジェネレーター関数を作成できます。通常の関数が 1 回だけ返すのではなく、ジェネレーターは反復する必要がある値を生成するために必要なだけ何度でも生成できます。
簡単な例は、ジェネレーターを使用して range() 関数を再実装することです。 標準の range() 関数は、戻り値ごとにメモリ内に配列を生成する必要があるため、非常に大きな配列が生成されます。 たとえば、 range(0, 1000000) を呼び出すと、メモリ使用量が 100 MB を超えます。
代わりに、Iterator オブジェクトを作成し、内部でジェネレーターの現在の状態を追跡するのに十分なメモリのみを必要とする xrange() ジェネレーターを実装することもできます。したがって、必要なメモリは 1K バイト未満です。
例 #1 range() をジェネレーターとして実装します
<?php function xrange($start, $limit, $step = 1) { if ($start < $limit) { if ($step <= 0) { throw new LogicException('step必须是正数'); } for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } else { if ($step >= 0) { throw new LogicException('step必须是负数'); } for ($i = $start; $i >= $limit; $i += $step) { yield $i; } } } /* 注意range() 和 xrange() 的结果在下面的统一输出中. */ echo '来自range()的单个奇数: '; foreach (range(1, 9, 2) as $number) { echo "$number "; } echo "\n"; echo '来自xrange()的单个奇数 '; foreach (xrange(1, 9, 2) as $number) { echo "$number "; } ?>
上記のルーチンは出力します:
Single digit odd numbers from range(): 1 3 5 7 9 Single digit odd numbers from xrange(): 1 3 5 7 9