PHP

PHP: ob_start() 関数によるバッファリングの動作

投稿日:2021年4月7日 更新日:

1. PHP の ob_start() 関数

PHP には ob_start() という関数があります。

公式マニュアルの説明では「出力のバッファリングを有効にする」とあるのですが、この「バッファリング」が実際どういった動作をするものなのか分かりにくいので簡単な図を書いてみました。

2. バッファリングがない状態

バッファリングがない状態の図が以下です。

バッファがないとき

この状態では、例えば echo "Hello!" と書いて実行すれば “Hello!” という文字列が画面に送られます。

3. ob_start() 関数によりバッファを作成する

ob_start() 関数を実行すると「バッファ」が作成されます(下の図では、四角形がバッファを表しています)。

「バッファ」は出力された文字列を受け取って溜めておくことができます。

バッファを3つ作成した場合

ob_start() を実行するたびに新たなバッファが作成され、新しいバッファは1つ前のバッファの上に積まれていきます(概念の話です)。そして、一番上のバッファだけが「出力」を受け取って溜めこんでいきます(出力は画面に送られません)。

4. バッファを削除する

ob_end_flush() 関数を実行すると、一番上のバッファが削除されます。

バッファを削除する

このとき、削除されるバッファが作成されたときに実行された ob_start() 関数に引数が与えられていなければ、そのバッファ内の文字列をそのまま一つ下のバッファに渡します。コールバック関数が渡されていた場合は、バッファ内の文字列を第一引数としてコールバック関数が実行され、その結果が一つ下のバッファに渡されます。

これ以降、出力された文字列は新たに一番上となったバッファが受け取ることになります。

5. 最後のバッファを削除する

作成されたバッファの数だけ ob_end_flush() 関数を実行すれば、バッファはすべて削除されます。

最後のバッファが削除された場合は、そのバッファ内の文字列を一つ下のバッファに渡すのではなく、画面に送ります。

最後のバッファを削除する

この場合も、そのバッファを作成したときの ob_start() 関数にコールバック関数が引数として渡されていれば、バッファ内の文字列を引数としてそのコールバック関数が実行され、その結果が画面に送られることになります。

バッファリングの説明は以上です。

6. WordPress のプラグインとバッファリング

WordPress で画面に出力される内容に対して何か処理したい場合、テーマの functions.php ファイル内で ob_start()関数(と ob_end_flush()関数)を記述することで実現することができます。

しかし、特定のプラグインでも ob_start()関数によるバッファリングが利用されているために、このプラグインからの出力内容がこちらで作成したバッファに入ってこない場合があります。

こんなときは、以下のタイミングに気を付けましょう。

  • このプラグインが ob_start() を実行する前にこちらの ob_start() を実行する。
  • このプラグインが ob_end_flush() を実行した後にこちらの ob_end_flush() を実行する。

これらのタイミングは、add_action()の第三引数(優先度)を調整することで対応できることが多いです。

7. 参考

📂-PHP

執筆者:labo


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

Google App Engine

SendGrid でメール送信する(Google App Engine, PHP7)

Google App Engine (runtime: php72) の環境における、SendGrid を使ったメール送信方法について説明しています。

Google App Engine

普通のPHPサイトをGAE(php72)上で実現する方法

普通のPHPサイトをGAE(php72)上で実現する方法について説明しています。

PHP

画像ファイルの拡張子でないURLから 画像ファイルを返すPHPコードの例

ウェブブラウザで画像ファイルをダウンロードする場合、URL は https://example.com/foo/bar.png というように、末尾がそのファイル名になっていることが多いと思います。 こ …

PHP

PHPで即時実行関数を使って名前空間を汚さない

JavaScript だとよく見るやり方なのですが、「即時実行関数を使って名前空間を汚さない」やり方って、PHP の場合はあまりやらないのでしょうか? PHPで関数を宣言すると、その名前はグローバル空 …

PHPでのエラー処理・例外処理

目次1. PHPの例外クラス2. 例外クラスの使い分け3. 独自アプリ用例外クラスの作成例と利用例4. 資料 1. PHPの例外クラス PHPには以下の例外クラスが組み込まれています。 PHPの例外ク …