haphpiness

These are things in PHP which make me genuinely_happy();

Generators and yield

Generators let you iterate over data without loading everything into memory. Process a million-row CSV, stream API results, or build infinite sequences — all with constant memory usage.

// Read a 10GB file with constant memory
function readLines(string $file): Generator {
    $handle = fopen($file, 'r');
    while (($line = fgets($handle)) !== false) {
        yield trim($line);
    }
    fclose($handle);
}

foreach (readLines('/var/log/huge.log') as $line) {
    // Each line is read one at a time — never all in memory
}

// Generate infinite sequences
function fibonacci(): Generator {
    [$a, $b] = [0, 1];
    while (true) {
        yield $a;
        [$a, $b] = [$b, $a + $b];
    }
}

// Delegate with yield from
function allUsers(): Generator {
    yield from getAdmins();        // Generator
    yield from getEditors();       // Generator
    yield from [User::guest()];    // Array — also works!
}

// Two-way communication with send()
function accumulator(): Generator {
    $total = 0;
    while (true) {
        $value = yield $total;
        $total += $value;
    }
}
$acc = accumulator();
$acc->current(); // 0
$acc->send(10);  // 10
$acc->send(20);  // 30

Generators follow the same Iterator interface as any other iterable, so they work seamlessly with foreach, phpiterator_to_array, and the spread operator.

Significance: Efficiency

Generators make memory efficiency the default rather than an optimization. Processing large datasets with generators uses the same clean syntax as processing small arrays — no pagination logic, no batch callbacks, no manual iterator implementations.