PHPのお勉強!

PHP TOP

ob_start

(PHP 4, PHP 5, PHP 7, PHP 8)

ob_start出力のバッファリングを有効にする

説明

ob_start(?callable $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 を返します。 コールバックのシグネチャは、次のとおりです。

handler(string $buffer, int $phase = ?): string
buffer
出力バッファの内容。
phase
PHP_OUTPUT_HANDLER_* 定数 のビットマスク

callbackfalse を返すと、元の入力がそのままブラウザに送信されます。

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()

戻り値

成功した場合に true を、失敗した場合に false を返します。

例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 コールバック関数

add a note

User Contributed Notes 39 notes

up
54
Ray Paseur (Paseur ... ImagineDB.com)
19 years ago
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();
?>
up
17
net_navard at yahoo dot com
18 years ago
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
up
27
ed.oohay (a) suamhcs_rodnan
21 years ago
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 =)
up
19
mjr
20 years ago
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')); ?>.
up
11
mchojrin at gmail dot com
12 years ago
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 :)
up
3
jhlavon
11 years ago
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") ;
...
}
up
6
Asher Haig (ahaig at ridiculouspower dot com)
17 years ago
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();
}
up
7
Chris
14 years ago
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.
up
2
jkloss at hotmail dot com
20 years ago
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.
up
4