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_start()。如果有多重输出缓冲区是活跃的,输出内容会一直按嵌套的顺序依次过滤。参阅嵌套输出缓冲区获取更多详情。

有关输出缓冲区的详细信息,请参阅用户级输出缓冲区

参数

callback

可以指定可选的 callback callable。也可以通过传递 null 来绕过它。

当冲刷(发送)、清理输出缓冲区或在脚本末尾冲刷输出缓冲区时,将调用 callback

callback 的签名如下:

handler(string $buffer, int $phase = ?): string
buffer
输出缓冲区中的内容。
phase
PHP_OUTPUT_HANDLER_* 常量PHP_OUTPUT_HANDLER_* 常量的位掩码。有关更多详细信息,请参阅传递给输出处理程序的 flag

如果 callback 返回 false,则返回缓冲区的内容。有关更多详细信息,请参阅 输出处理程序的返回值

警告

从输出处理程序中调用以下任何函数都将导致 fatal 错误 ob_clean()ob_end_clean()ob_end_flush()ob_flush()ob_get_clean()ob_get_flush()ob_start()

有关 callback(输出处理程序)的更多详细信息,请参阅输出处理程序使用输出处理程序

chunk_size

如果传递了可选参数 chunk_size,则在任何导致缓冲区长度等于或大于 chunk_size 的代码块的输出之后,都会冲刷缓冲区。默认值 0 表示缓冲所有输出,直到缓冲区关闭。更多详细信息,请参阅缓冲区大小

flags

flags 参数是位掩码,用于控制可以在输出缓冲区上执行的操作。默认是允许清理、冲刷和移除输出缓冲区,可以通过缓冲区控制 flag手动设置。参阅缓冲区中允许的操作获取更多详细信息。

每个标志都控制着对一组功能的访问,详细介绍如下:

常量 函数
PHP_OUTPUT_HANDLER_CLEANABLE ob_clean()
PHP_OUTPUT_HANDLER_FLUSHABLE 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)
{
// replace all the apples with 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);

?>

参见

添加备注

用户贡献的备注 6 notes

up
53
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
20
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
28
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
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
3
ernest at vogelsinger dot at
19 years ago
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.
To Top