ob_start
(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()
例
例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);
?>
参考
- ob_get_contents() - 出力用バッファの内容を返す
- ob_end_clean() - アクティブな出力用バッファをクリア(消去)し、出力のバッファリングをオフにする
- ob_end_flush() - アクティブな出力用バッファをフラッシュ(送信)し、アクティブな出力バッファをオフにする
- ob_implicit_flush() - 自動フラッシュをオンまたはオフにする
- ob_gzhandler() - 出力バッファを gzip 圧縮するための ob_start コールバック関数
- ob_iconv_handler() - 出力バッファハンドラとして文字エンコーディングを変換する
- mb_output_handler() - 出力バッファ内で文字エンコーディングを変換するコールバック関数
- ob_tidyhandler() - バッファを修正するための ob_start コールバック関数
User Contributed Notes 39 notes
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 =)
If you're using object-orientated code in PHP you may, like me, want to use a call-back function that is inside an object (i.e. a class function). In this case you send ob_start a two-element array as its single argument. The first element is the name of the object (without the $ at the start), and the second is the function to call. So to use a function 'indent' in an object called '$template' you would use <?php ob_start(array('template', 'indent')); ?>.
Just a word of warning to those like myself who are upgrading from 5.3. I have a piece of code that used to work:
<?php
if ( !ob_start( !DEBUGMODE ? 'ob_gzhandler' : '' ) ) {
ob_start();
}
?>
Which is not working anymore (I get an error like: Warning: ob_start(): function '' not found or invalid function name).
It's easily fixed though, just changed the '' to a null, like this:
<?php
if ( !ob_start( !DEBUGMODE ? 'ob_gzhandler' : null ) ) {
ob_start();
}
?>
Which preserves the code intention but works :)
When used in constructor part of class it have to be prefixed by "self::" or by classname, else PHP fails to create buffer.
function __construct ()
{
$bo = ob_start ("self::callback_ob") ;
...
}
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.
If ob_start does not seem to be working for you, note that with Apache 2 the flush() function causes PHP to send headers regardless of whether ob_start had been called before flush.
ob_start();
echo 'test';
flush();
will cause Apache 2 to send whatever headers may be stacked up - which means you can't use a header(location:xxx) after the flush. To fix, remove the flush(). Spent several hours discovering this. Apache 1.x didn't work this way.