Generator adalah cara elegan untuk mengiterasi data TANPA memuat semuanya ke memory sekaligus. Fungsi generator menggunakan keyword yield sebagai pengganti return.
Masalah: memuat array besar ke memory
function rangeBesar(int $n): array {
$hasil = [];
for ($i = 0; $i < $n; $i++) {
$hasil[] = $i;
}
return $hasil; // Butuh memory untuk SEMUA elemen
}
foreach (rangeBesar(1_000_000) as $n) { ... }
// ⚠️ Alokasi ~32 MB
Solusi: generator dengan yield:
function rangeGen(int $n) {
for ($i = 0; $i < $n; $i++) {
yield $i; // Produce satu nilai, pause, lanjut saat diminta
}
}
foreach (rangeGen(1_000_000) as $n) { ... }
// ✓ Memory konstan — tiap nilai dihitung sesuai permintaan
Saat foreach minta nilai berikutnya, generator dilanjutkan sampai yield berikutnya.
yield key => value:
function pasangan() {
yield "nama" => "Budi";
yield "umur" => 25;
yield "kota" => "Jakarta";
}
foreach (pasangan() as $key => $value) {
echo "$key: $value\n";
}
yield from (PHP 7+) — delegasi ke generator lain:
function angkaGenap() {
yield 2;
yield 4;
}
function semua() {
yield 1;
yield from angkaGenap(); // 2, 4
yield 5;
}
foreach (semua() as $n) {
echo "$n "; // 1 2 4 5
}
Use case nyata:
- Baca file besar baris-per-baris:
function bacaBaris(string $path) {
$fh = fopen($path, "r");
while (($line = fgets($fh)) !== false) {
yield trim($line);
}
fclose($fh);
}
// Bisa proses file 10 GB tanpa out-of-memory!
foreach (bacaBaris("akses.log") as $line) {
// proses
}
- Sequence tak terbatas:
function fibonacci() {
$a = 0; $b = 1;
while (true) {
yield $a;
[$a, $b] = [$b, $a + $b];
}
}
$fib = fibonacci();
foreach ($fib as $i => $n) {
if ($i >= 10) break;
echo "$n ";
}
// 0 1 1 2 3 5 8 13 21 34
- Laravel Lazy Collection:
LazyCollection::make(fn() => yield from ...)— pattern yang sama untuk dataset raksasa di Laravel.
Kapan pakai generator?
- Dataset besar / tak terbatas
- Streaming file, network, DB cursor
- Pipeline transformasi (map/filter lazy)
Kapan tidak?
- Data kecil yang perlu di-random-access (
$arr[$i]) — pakai array biasa - Kamu perlu
count()atau iterasi berkali-kali — generator hanya bisa dikonsumsi sekali