PHP を使っていて、echo や printf 関数を使って下記のような現象に遭遇したことはありませんか?
echo や printf の結果がすぐに出力されない!!
私はワードプレステーマ開発のデバッグ(ステップ実行)をしていて、echo や printf の出力が遅れることに気づきました。
実はこれは PHP の機能の一つである「出力バッファリング」が影響しています。この「出力バッファリング」を無効化することで echo や printf の結果をすぐに出力することが可能になります。
このページでは、まずこの出力バッファリングについて解説し、続いて出力バッファリングを無効化して echo や printf の結果をすぐに出力する方法について解説したいと思います。
Contents
出力バッファリング
それでは出力バッファリングとはどのようなものであるかについて解説していきます。
出力バッファリングとは
出力バッファリングとは echo や printf での出力結果を一旦バッファに溜め込む機能になります。
バッファに溜め込んだ出力結果は、バッファがいっぱいになった場合やプログラム終了時、flush が行われた時に、一気にコンソールやファイルに出力します。
スポンサーリンク
出力バッファリングのメリット
出力バッファリングのメリットは実行速度の向上の効果があることです。出力バッファリングにより、コンソールやファイルに出力する回数が減りますので、その分負荷が減り実行速度が向上します。
出力バッファリングのデメリット
出力バッファリングのデメリットはバッファリング用のバッファの分、余計にメモリが必要になることです。ただし、最近のパソコンやサーバーではメモリが十分ありますので、このデメリットはほぼ気にならないと思います。
出力バッファリングのもう一つのデメリットは echo や printf による出力が遅れることです。これは特にデバッグ時に出力結果を1行ずつ確認したい場合に不便です。
出力バッファリング設定の確認
出力バッファリングが有効化されているかどうかはPHPの設定で確認可能です。
PHP の設定は、PHP プログラムで「phpinfo();」を実行する or コマンドラインで php -i を実行することで出力可能です。出力結果の中に「output_buffering」という設定項目があり、この「output_buffering」の設定値が “0” 以外であれば出力バッファリングが有効化されています。
さらに、この output_buffering の値は出力バッファの大きさ(Byte)となります。
スポンサーリンク
出力バッファリングの無効化
出力バッファリングを無効化することにより、echo や printf の出力結果がバッファに溜められることなく即座にコンソールやファイルに書き出しされるようになります。ここではこの出力バッファリングを無効化する方法を2つ紹介します。
PHPプログラム中で出力バッファリングを無効化する
PHP プログラムの先頭で ob_end_flush 関数を実行することで出力バッファリングを無効化することが可能です。これにより、そのプログラムでは出力バッファリングが無効化され、echo や printf の出力が即座に実行されるようになります。
ob_end_flush 関数は、出力バッファにたまっているデータを出力し、さらに出力バッファリングを無効化する関数です。ですので、この関数をプログラムの先頭で実行すれば、その後は出力バッファリングが無効化された状態でプログラムが動作することになります。
例えば下記プログラムのように ob_end_flush 関数を実行すれば良いです。
<?php
ob_end_flush();
echo "test";
sleep(10);
echo "test2";
?>
出力バッファリングが有効化されている場合、もし ob_end_flush() を実行しなければ test も test2 もプログラム終了時に一気に出力されます。しかし、出力バッファリングが有効化されている場合でも、ob_end_flush() を実行すると、test が即時に出力され、その10秒後に test2 が出力されます。
ワードプレスで出力バッファリングを無効化するのであれば、最初に実行される index.php (ワードプレスインストールフォルダにある index.php)の先頭に ob_end_flush 関数を実行するのが良いと思います。
ob_end_flush();
define( 'WP_USE_THEMES', true );
/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );
逆に出力バッファリングが無効化されている時に有効化したい場合は、プログラム中で ob_start 関数を実行すれば良いです。
PHP設定で出力バッファリングを無効化する(上級者向け)
php.ini の設定を直接変更することでも出力バッファリングの無効化を行うことが可能です。
まず php.ini の中から output_buffering 設定を行なっている場所を探します。私の php.ini では下記のように設定が行われていました(output_buffering は有効で、バッファサイズは 4096 Byte)。
output_buffering = 4096
この output_buffering の設定値を “0” に変更することで出力バッファリングの無効化が行えます。
output_buffering = 0
MAMP でワードプレスを動作させている場合などは、php.ini の変更を反映するためにはサーバー(Apache Serverなど)の再起動が必要です。ですので、サーバーが起動している場合は、一旦サーバーを停止し、再度サーバーを起動してサーバーの再起動を行ってください。
これにより出力バッファリングの無効化が行えます。ただし、出力バッファリングを無効化してしまうと echo や printf 実行時の負荷が大きくなります。ウェブサイトを公開しているウェブサーバーの php.ini を変更して出力バッファリングを無効化してしまうとページ表示が遅くなる可能性がありますので注意してください(デバッグ等で無効化するだけであれば問題はありません)。
スポンサーリンク
まとめ
echo や printf で即座に文字列が出力されない原因は出力バッファリングが有効化されていることです。
リアルタイムに出力されるようにしたい場合は、PHPプログラムで ob_flush_end 関数を実行するか、php.ini の output_buffering の設定値を “0” にして出力バッファリングを無効化しましょう。
ただし出力バッファリングを無効化すると処理速度が低下する可能性があります。ワードプレスのデバッグ等を行うときに無効化する分には問題ありませんが、公開する際には出力バッファリングは有効化しておく方が良いです。