Generators — PHP

Generator adalah cara elegan untuk mengiterasi data TANPA memuat semuanya ke memory sekaligus. Fungsi generator menggunakan keyword yield sebagai pengganti retu

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:

  1. 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
}
  1. 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
  1. Laravel Lazy Collection: LazyCollection::make(fn() => yield from ...) — pattern yang sama untuk dataset raksasa di Laravel.

Kapan pakai generator?

Kapan tidak?

Yang akan kamu pelajari