PHP5.5からの機能。
基本的にはforeachで回す。
function rangeGenerator($start, $limit) {
for ($i = $start; $i < $limit; $i++) {
yield $i;
}
}
foreach (rangeGenerator(1, 9) as $number) {
echo "$number ";
}
// 1 2 3 4 5 6 7 8
ただ今回、foreachを使わず任意のタイミングで、でも順番に次の値を取得したい場合があったので、やり方をメモ。大まかには、ジェネレータオブジェクトを取得し、用意された関数を呼ぶとよい。
echo '<pre>';
function generatorTest()
{
echo 'GEN_START' . PHP_EOL;
yield 0;
foreach (range(1, 10) as $i) {
echo $i . PHP_EOL;
yield $i + 100;
}
}
$gen = generatorTest(); // (ジェネレータオブジェクトを返すだけで、何も出力しない)
echo 'START' . PHP_EOL; // START
echo $gen->current() . PHP_EOL; // GEN_START (ジェネレータ内部のecho)
// 0 (ジェネレータから0が返される)
$gen->next(); // 1 (ジェネレータ内部のecho)
echo 'B' . PHP_EOL; // B
echo $gen->current() . PHP_EOL; // 101 (101が返される)
echo $gen->current() . PHP_EOL; // 101 (何度でも101が返される)
$gen->next(); // 2 (ジェネレータ内部のecho)
$gen->next(); // 3 (ジェネレータ内部のecho)
echo '</pre>';
next()は次のyieldまで進めるだけで、値は返さない。
最初にいきなりnext()を呼ぶと、2つ目のyieldまでが一度に処理されてしまう。
echo '<pre>';
function generatorTest2()
{
foreach (range(1, 10) as $i) {
echo $i . PHP_EOL;
yield $i + 100;
}
}
$gen = generatorTest2(); //
$gen->next(); // 1 (ジェネレータ内部のecho)
// 2 (ジェネレータ内部のecho)
echo $gen->current() . PHP_EOL; // 102
echo '</pre>';
つまりジェネレータのyieldを順番に返したいだけなら、まずcurrent()を呼んでから、次のためにnext()を呼ぶ、ということになる。
要素が残っているかのチェックは、valid()でできる。