{
    "slug": "output_buffering",
    "term": "Output Buffering (ob_start / ob_flush)",
    "category": "php",
    "difficulty": "intermediate",
    "short": "Capturing PHP output into a buffer rather than sending it immediately, enabling manipulation before delivery or header modification.",
    "long": "PHP's output buffering (ob_start(), ob_get_clean(), ob_flush()) intercepts all echo/print output into an internal buffer. This enables: modifying output after generation (adding compression, injecting content), sending headers after output has started (workaround for 'headers already sent' errors — though proper code shouldn't need this), capturing template output as a string, and implementing full-page caching. Nested buffers are supported. ob_gzhandler compresses output — but prefer server-level compression. Forgetting to flush or clean a buffer on exceptions is a common source of partially-delivered or corrupted responses.",
    "aliases": [
        "ob_start",
        "PHP output buffering",
        "ob_get_clean"
    ],
    "tags": [
        "php",
        "performance",
        "headers"
    ],
    "misconception": "Output buffering is only useful for capturing template output. It also allows headers to be sent after output has started (by buffering the output), enables response compression, and is used by frameworks to implement response interception and modification.",
    "why_it_matters": "Output buffering captures output before sending it — enabling headers to be set after content begins, reducing network round-trips, and allowing content to be modified or discarded before delivery.",
    "common_mistakes": [
        "Calling header() after output has been sent — 'headers already sent' error caused by missing ob_start().",
        "Not calling ob_end_clean() or ob_end_flush() — nested buffers cause memory leaks in long-running scripts.",
        "Relying on output buffering to fix poorly structured code instead of fixing the output order.",
        "Not knowing that PHP-FPM and some SAPIs have implicit output buffering — behaviour differs across environments."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "gzip_compression",
        "php_fpm",
        "error_handling"
    ],
    "prerequisites": [
        "php_fpm",
        "performance_degradation",
        "http_request_response_cycle"
    ],
    "refs": [
        "https://www.php.net/manual/en/book.outcontrol.php"
    ],
    "bad_code": "// Headers already sent — ob_start() would fix this:\necho 'Some content'; // Output sent\nheader('Location: /dashboard'); // Warning: headers already sent\n\n// Fix:\nob_start();\necho 'Some content';\nheader('Location: /dashboard');\nob_end_clean();\nexit;",
    "good_code": "// ob_start() captures all output until ob_end_flush()/ob_get_clean()\nob_start();\nrequire 'template.php'; // outputs HTML\n$html = ob_get_clean(); // capture and stop buffering\n\n// Send custom headers before any output — ob_start() buys time\nob_start();\n// ... lots of processing that might echo ...\nheader('X-Processing-Time: ' . $elapsed); // still works — nothing sent yet\nob_end_flush();\n\n// Template rendering pattern\nfunction render(string $template, array $vars): string {\n    extract($vars, EXTR_SKIP);\n    ob_start();\n    require \"views/{$template}.php\";\n    return ob_get_clean();\n}\n$html = render('email/welcome', ['user' => $user]);",
    "quick_fix": "Use ob_start() at the top of templates to capture output and manipulate it before sending — but avoid buffering entire large responses in memory; send chunked with flush() for streaming",
    "severity": "low",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/output_buffering",
        "html_url": "https://codeclaritylab.com/glossary/output_buffering",
        "json_url": "https://codeclaritylab.com/glossary/output_buffering.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": "[Output Buffering (ob_start / ob_flush)](https://codeclaritylab.com/glossary/output_buffering) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/output_buffering"
            }
        }
    }
}