出力バッファリング制御は知っている人は良く使うけど、知らない人は全く使わないという偏りがある関数群ですが、知っていると便利です。
Contents
出力バッファリングってなに?
出力バッファリングは「画面にすぐ表示せず、ためておく技術」
「すぐ表示」とは?
echo や print や var_dump()、それからHTMLそのものも、
PHPが読み込んでる最中に直接「標準出力(STDOUT)」に流れていく出力のことです

「標準出力」とは?
PHPはコマンドラインでも使えるから、そのときは echo はそのままターミナルに出力される。
でもWeb経由のPHPの場合は
「標準出力」=「クライアント(ブラウザ)に送るHTTPレスポンス本文」

ウェブサーバーで実行されるPHPファイルの場合

例1 echo
<!DOCTYPE html>
<html>
<body>
<p>HTMLで出力1</p>
<?php
echo "<p>PHPで出力1</p>";
echo "<p>PHPで出力2</p>";
?>
<p">HTMLで出力2</p>
<?php
echo "<p>PHPで出力3</p>";
?>
</body>
</html>↓
HTMLで出力1
PHPで出力1
PHPで出力2
HTMLで出力2
PHPで出力3例1 Warning
エラーについても標準出力で同様に上から順になります。
<?php
echo "1. 最初の出力";
// 存在しない変数でWarning発生
echo $undefined_variable;
echo "2. 次の出力";
// 存在しないファイルでWarning発生
include 'nonexistent.php';
echo "3. 最後の出力";
?>↓
1. 最初の出力
Warning: Undefined variable $undefined_variable in /var/www/html/error-test-stdout.php on line 5
2. 次の出力
Warning: include(nonexistent.php): Failed to open stream: No such file or directory in /var/www/html/error-test-stdout.php on line 10
Warning: include(): Failed opening 'nonexistent.php' for inclusion (include_path='.:/usr/local/lib/php') in /var/www/html/error-test-stdout.php on line 10
3. 最後の出力| 出力種別 | どこに出る? | すぐ表示? | 備考 |
|---|---|---|---|
echo, print, HTML | 標準出力(stdout) | ✅ すぐ表示 | ブラウザに出る |
var_dump() | 標準出力 | ✅ すぐ表示 | デバッグ用 |
fwrite(STDERR) | エラー出力 | ❌ 表示されない | CLIで使うことが多い |
file_put_contents() | ファイル | ❌ 表示されない | ログや保存用 |
mail() | メール | ❌ 表示されない | サーバーから外部に送る |
setcookie() | ヘッダー出力 | ❌ 表示されない | bodyより先に送る必要あり |
🔽 出力バッファリングを使うと
- 出力内容を一時的にメモリ上にためておいて
- あとからまとめて送る、あるいは加工してから送ることができる!
| 関数名 | 説明 |
|---|---|
ob_start() | 出力バッファリングを開始する |
ob_get_contents() | バッファにたまっている内容を取得する |
ob_end_clean() | バッファの内容を消してバッファリングを終了 |
ob_end_flush() | バッファ内容を出力してからバッファリング終了 |
ob_clean() | バッファ内容を消去(バッファリングは継続) |
ob_flush() | バッファ内容を出力(バッファリングは継続) |
バッファ処理が使われる主な理由
テンプレートキャプチャ
ob_start();
include 'template.php';
$content = ob_get_clean(); // テンプレートの出力を文字列として取得ヘッダーより前に出力がある場合
header()関数で設定したものがHTTPレスポンスヘッダーになります。
<?php
// ヘッダー設定
header('Content-Type: text/html; charset=UTF-8');
header('Location: /thanks.php'); // リダイレクト
// ボディ(標準出力)
echo "完了しました";
?>header()は出力より前に書く必要があります。
<?php
// ❌ エラー
echo "Hello";
header('Location: /page.php'); // エラー!
// ✅ 正しい
header('Location: /page.php');
echo "Hello";
?>↓ 解決策
<?php
ob_start(); // バッファリング開始
echo "Hello"; // まだ実際には出力されない
header('Location: /page.php'); // OK
ob_end_flush();
?>出力のタイミング制御(headerより前に出力があった時)
ob_start();
echo "処理開始";
header("Location: /done.php"); // ← バッファがなければエラーになる
ob_end_flush();