はじめに
PHP のジェネレーターは「大量のデータを一度にメモリに展開せず、必要な分だけ順に取り出せる便利な仕組み」です。ただし foreach との相性は抜群ですが、for 文にはあまり向きません。
この記事では、その理由と正しい使い方を整理します。
目次
ジェネレーターとは?
ジェネレーターは yield
キーワードを使って値を「逐次的に」返す関数です。
呼び出すと Generator オブジェクト(Iterator を実装)として返されます。
function hoge() {
for ($i = 0; $i < 10; ++$i) {
yield $i * 10;
}
}
$data = hoge(); // Generator オブジェクト
foreach とジェネレーターの相性
ジェネレーターは Iterator を実装しているので、foreach
と組み合わせるとそのまま使えます。
foreach (hoge() as $val) {
echo $val, PHP_EOL;
}
出力:
0
10
20
...
90
内部的には rewind() → valid() → current() → key() → next()
が自動的に呼ばれ、1件ずつ値を取り出せます。
for 文との相性
一方、for
文は「配列」を前提としています。
$data = hoge();
var_dump($data[4]); // ❌ エラー
Fatal error: Uncaught Error: Cannot use object of type Generator as array
ジェネレーターは配列ではないので ランダムアクセスできない のです。もし for
文で使いたければ、一度配列に変換する必要があります。
ジェネレーターから配列の変換
$arr = iterator_to_array(hoge());
for ($i = 0; $i < count($arr); $i++) {
echo $arr[$i], PHP_EOL;
}
まとめ
- ジェネレーターは foreach に最適(逐次処理・省メモリ)
- for 文は不向き(配列インデックスを前提としているため)
- ランダムアクセスが必要なら 配列化 (
iterator_to_array
) を使う