(PHP 4, PHP 5, PHP 7, PHP 8)
ob_start — 出力のバッファリングを有効にする
$callback
= null
, int $chunk_size
= 0, int $flags
= PHP_OUTPUT_HANDLER_STDFLAGS
): bool この関数は出力のバッファリングをオンにします。 出力のバッファリングを有効にすると、 (ヘッダ以外の) スクリプトからの出力は実際には行われず、 代わりに内部バッファに保存されます。
この内部バッファの内容は、ob_get_contents() を用いて文字列変数にコピーされます。 内部バッファの内容を出力するには ob_end_flush() を使用します。 ob_end_clean() は、バッファの内容を出力せずに消去します。
web サーバーによっては (例: Apache)、コールバック関数からコールされた際に、
スクリプトの実行ディレクトリを変更するものがあります。
コールバック関数の内部で chdir(dirname($_SERVER['SCRIPT_FILENAME']))
などと指定することで、これをもとに戻すことが可能です。
出力バッファはスタッカブルであり、このため、他の ob_start() がアクティブの間に ob_start() をコールすることが可能です。この場合、 ob_end_flush() を適切な回数コールするようにしてください。 複数の出力コールバック関数がアクティブの場合、 ネストした順番で逐次連続的に出力がフィルタ処理されます。
スクリプトが終了した際に、 出力バッファリングがまだアクティブな場合、 PHP はバッファリングされた内容を自動的に出力します。
callback
オプションの引数 callback
関数を指定することが可能です。この関数は、パラメータとして文字列をとり、
文字列を返します。このコールバック関数は、
出力バッファがフラッシュ (送信) あるいは消去
(ob_flush() , ob_clean()
あるいは同等の関数で) された場合、
またはリクエストの最後にブラウザに出力をフラッシュする際にコールされます。
callback
がコールされた際に、
この関数は出力バッファの内容をパラメータとして受け取ります。このコールバック関数は、
新規の出力バッファを実際に出力される結果として返す必要があり、
この結果はブラウザに送信されます。
callback
がコール可能な関数ではない場合は
false
を返します。
コールバックのシグネチャは、次のとおりです。
buffer
phase
PHP_OUTPUT_HANDLER_*
定数 のビットマスク
callback
が false
を返すと、元の入力がそのままブラウザに送信されます。
callback
パラメータに null
値を渡すと、
これをバイパスすることができます。
ob_end_clean() 、
ob_end_flush() 、ob_clean() 、
ob_flush() および ob_start()
をコールバック関数の内部からコールすることはできません。
実際にコールした際の挙動は未定義です。バッファの内容を消去したい際には、
コールバック関数から "" (空文字列) を返してください。
同じく、print_r($expression, true)
や
highlight_file($filename, true)
のような
出力バッファリング関数も、
コールバック関数の内部からコールすることはできません。
注意:
Web ページの圧縮をサポートする圧縮 gz エンコード されたデータの Web ブラウザへの送信を容易にするために ob_gzhandler() が存在します。 ob_gzhandler() は、ブラウザが受け入れる content encoding の型を調べ、それに基づいて出力を返します。
chunk_size
オプションのパラメータ chunk_size
が渡された場合、
バッファの長さが chunk_size
バイトを超えるたびに、
出力の後でバッファがフラッシュされます。
デフォルト値は 0
で、これは出力関数がコールされるのが
出力バッファが閉じたときだけであることを意味します。
flags
flags
はビットマスクで、出力バッファ上でどんな操作ができるのかを制御します。
デフォルトでは、出力バッファのクリーン、フラッシュ、削除がすべてできるようになっています。
これは、
出力バッファの制御フラグ
を経由して明示的に設定できます。
詳細は バッファに対して可能な操作
を参照ください。
各フラグが、次の表のように関数へのアクセスを制御します。
定数 | 関数 |
---|---|
PHP_OUTPUT_HANDLER_CLEANABLE |
ob_clean() |
PHP_OUTPUT_HANDLER_FLUSHABLE |
ob_end_flush() ob_flush() |
PHP_OUTPUT_HANDLER_REMOVABLE |
ob_end_clean() , ob_end_flush() , ob_get_clean() , ob_get_flush() |
注意: PHP 8.4.0 より前のバージョンでは、flags パラメータに 出力ハンドラのステータスフラグ も指定可能でした。
例1 ユーザー定義のコールバック関数の例
<?php
function callback($buffer)
{
// apples を全て oranges に置換する
return (str_replace("apples", "oranges", $buffer));
}
ob_start("callback");
?>
<html>
<body>
<p>It's like comparing apples to oranges.</p>
</body>
</html>
<?php
ob_end_flush();
?>
上の例の出力は以下となります。
<html> <body> <p>It's like comparing oranges to oranges.</p> </body> </html>
例2 削除不可能な出力バッファを作る例
<?php
ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_REMOVABLE);
?>
You can use PHP to generate a static HTML page. Useful if you have a complex script that, for performance reasons, you do not want site visitors to run repeatedly on demand. A "cron" job can execute the PHP script to create the HTML page. For example:
<?php // CREATE index.html
ob_start();
/* PERFORM COMLEX QUERY, ECHO RESULTS, ETC. */
$page = ob_get_contents();
ob_end_clean();
$cwd = getcwd();
$file = "$cwd" .'/'. "index.html";
@chmod($file,0755);
$fw = fopen($file, "w");
fputs($fw,$page, strlen($page));
fclose($fw);
die();
?>
Hello firends
ob_start() opens a buffer in which all output is stored. So every time you do an echo, the output of that is added to the buffer. When the script finishes running, or you call ob_flush(), that stored output is sent to the browser (and gzipped first if you use ob_gzhandler, which means it downloads faster).
The most common reason to use ob_start is as a way to collect data that would otherwise be sent to the browser.
These are two usages of ob_start():
1-Well, you have more control over the output. Trivial example: say you want to show the user an error message, but the script has already sent some HTML to the browser. It'll look ugly, with a half-rendered page and then an error message. Using the output buffering functions, you can simply delete the buffer and sebuffer and send only the error message, which means it looks all nice and neat buffer and send
2-The reason output buffering was invented was to create a seamless transfer, from: php engine -> apache -> operating system -> web user
If you make sure each of those use the same buffer size, the system will use less writes, use less system resources and be able to handle more traffic.
With Regards, Hossein
Output Buffering even works in nested scopes or might be applied in recursive structures... thought this might save someone a little time guessing and testing :)
<pre><?php
ob_start(); // start output buffer 1
echo "a"; // fill ob1
ob_start(); // start output buffer 2
echo "b"; // fill ob2
$s1 = ob_get_contents(); // read ob2 ("b")
ob_end_flush(); // flush ob2 to ob1
echo "c"; // continue filling ob1
$s2 = ob_get_contents(); // read ob1 ("a" . "b" . "c")
ob_end_flush(); // flush ob1 to browser
// echoes "b" followed by "abc", as supposed to:
echo "<HR>$s1<HR>$s2<HR>";
?></pre>
... at least works on Apache 1.3.28
Nandor =)
When a script ends, all buffered output is flushed (this is not a bug: http://bugs.php.net/bug.php?id=42334&thanks=4). What happens when the script throws an error (and thus ends) in the middle of an output buffer? The script spits out everything in the buffer before printing the error!
Here is the simplest solution I have been able to find. Put it at the beginning of the error handling function to clear all buffered data and print only the error:
$handlers = ob_list_handlers();
while ( ! empty($handlers) ) {
ob_end_clean();
$handlers = ob_list_handlers();
}
Careful with while using functions that change headers of a page; that change will not be undone when ending output buffering.
If you for instance have a class that generates an image and sets the appropriate headers, they will still be in place after the end of ob.
For instance:
<?php
ob_start();
myClass::renderPng(); //header("Content-Type: image/png"); in here
$pngString = ob_get_contents();
ob_end_clean();
?>
will put the image bytes into $pngString, and set the content type to image/png. Though the image will not be sent to the client, the png header is still in place; if you do html output here, the browser will most likely display "image error, cannot be viewed", at least firefox does.
You need to set the correct image type (text/html) manually in this case.
When you rely on URL rewriting to pass the PHP session ID you should be careful with ob_get_contents(), as this might disable URL rewriting completely.
Example:
ob_start();
session_start();
echo '<a href=".">self link</a>';
$data = ob_get_contents();
ob_end_clean();
echo $data;
In the example above, URL rewriting will never occur. In fact, rewriting would occur if you ended the buffering envelope using ob_end_flush(). It seems to me that rewriting occurs in the very same buffering envelope where the session gets started, not at the final output stage.
If you need a scenario like the one above, using an "inner envelope" will help:
ob_start();
ob_start(); // add the inner buffering envelope
session_start();
echo '<a href=".">self link</a>';
ob_end_flush(); // closing the inner envelope will activate URL rewriting
$data = ob_get_contents();
ob_end_clean();
echo $data;
In case you're interested or believe like me that this is rather a design flaw instead of a feature, please visit bug #35933 (http://bugs.php.net/bug.php?id=35933) and comment on it.