{
    "slug": "generators",
    "term": "Generators & yield",
    "category": "php",
    "difficulty": "intermediate",
    "short": "Generators allow iterating over large datasets lazily using yield, without loading everything into memory at once.",
    "long": "A generator function uses yield to produce values one at a time, pausing execution between yields. The caller receives a Generator object implementing the Iterator interface. This enables processing of large files, database result sets, or infinite sequences with O(1) memory usage rather than O(n). yield from enables delegation to another generator or iterable. Generators also support bidirectional communication — callers can send values back to the generator via Generator::send().",
    "aliases": [
        "PHP generators",
        "yield",
        "lazy iteration"
    ],
    "tags": [
        "php",
        "performance",
        "memory",
        "functional"
    ],
    "misconception": "Generators are just a fancy way to return arrays. Generators produce values lazily — each value is computed only when requested. Processing a 10-million-row dataset with a generator uses constant memory; building the same array first exhausts memory.",
    "why_it_matters": "Generators process sequences lazily — they yield one item at a time rather than building the entire collection in memory. For large datasets (CSV exports, database cursors, log streams) they are the difference between 10 MB memory usage and an out-of-memory crash.",
    "common_mistakes": [
        "Using a generator where you need to rewind or count — generators are forward-only and single-use.",
        "Forgetting that yield pauses execution — side effects before yield do not run until the generator is iterated.",
        "Returning a value from a generator with return instead of yield — it sets the return value, not a yielded item.",
        "Not wrapping database cursor generators in try/finally to ensure the connection is closed on early exit."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "array_functions",
        "excessive_file_io",
        "memory_leak"
    ],
    "prerequisites": [
        "php_iterators",
        "memory_management",
        "lazy_loading"
    ],
    "refs": [
        "https://www.php.net/manual/en/language.generators.php"
    ],
    "bad_code": "// Loading all rows into memory:\nfunction getAllUsers(): array {\n    return $this->db->query('SELECT * FROM users')->fetchAll(); // 1M rows in RAM\n}\n\n// Generator — yields one at a time:\nfunction streamUsers(): Generator {\n    $stmt = $this->db->query('SELECT * FROM users');\n    while ($row = $stmt->fetch()) yield $row;\n}",
    "good_code": "// Process large CSV without loading it all into memory\nfunction readCsv(string $path): Generator {\n    $fp = fopen($path, 'r');\n    try {\n        while (($row = fgetcsv($fp)) !== false) {\n            yield $row;\n        }\n    } finally {\n        fclose($fp);\n    }\n}\n\nforeach (readCsv('million_rows.csv') as $row) {\n    processRow($row); // constant memory — one row at a time\n}\n\n// Infinite sequence\nfunction fibonacci(): Generator {\n    [$a, $b] = [0, 1];\n    while (true) {\n        yield $a;\n        [$a, $b] = [$b, $a + $b];\n    }\n}\n$fib = fibonacci();\necho $fib->current(); // 0\n$fib->next();\necho $fib->current(); // 1",
    "quick_fix": "Replace functions that build and return large arrays with generators using yield — memory stays constant regardless of dataset size",
    "severity": "medium",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/generators",
        "html_url": "https://codeclaritylab.com/glossary/generators",
        "json_url": "https://codeclaritylab.com/glossary/generators.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Generators & yield](https://codeclaritylab.com/glossary/generators) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/generators"
            }
        }
    }
}