← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Output Buffering (ob_start / ob_flush)

php PHP 4.0+ Intermediate

Also Known As

ob_start PHP output buffering ob_get_clean

TL;DR

Capturing PHP output into a buffer rather than sending it immediately, enabling manipulation before delivery or header modification.

Explanation

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.

Common 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.

Code Examples

✗ Vulnerable
// Headers already sent — ob_start() would fix this:
echo 'Some content'; // Output sent
header('Location: /dashboard'); // Warning: headers already sent

// Fix:
ob_start();
echo 'Some content';
header('Location: /dashboard');
ob_end_clean();
exit;
✓ Fixed
// ob_start() captures all output until ob_end_flush()/ob_get_clean()
ob_start();
require 'template.php'; // outputs HTML
$html = ob_get_clean(); // capture and stop buffering

// Send custom headers before any output — ob_start() buys time
ob_start();
// ... lots of processing that might echo ...
header('X-Processing-Time: ' . $elapsed); // still works — nothing sent yet
ob_end_flush();

// Template rendering pattern
function render(string $template, array $vars): string {
    extract($vars, EXTR_SKIP);
    ob_start();
    require "views/{$template}.php";
    return ob_get_clean();
}
$html = render('email/welcome', ['user' => $user]);

Added 15 Mar 2026
Edited 22 Mar 2026
Views 16
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 1 ping W 2 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Amazonbot 6 Google 2 ChatGPT 2 Perplexity 1 Ahrefs 1
crawler 10 crawler_json 2
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Medium
⚡ 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
📦 Applies To
PHP 4.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
headers already sent errors from output before header(); large response built entirely in memory before sending; no output buffering in templates
Auto-detectable: ✗ No phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Low Context: Function

✓ schema.org compliant