ob_implicit_flush

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

ob_implicit_flush启用/禁用隐式刷新

说明

ob_implicit_flush(bool $enable = true): void

ob_implicit_flush() 将启用或禁用隐式刷新。隐式刷新将在每个生成输出的代码块之后执行刷新操作,因此不再需要对 flush() 的显式调用。

注意: 打印空字符串或发送头信息不被视为输出,不会导致刷新操作。

注意: 此函数对用户级输出处理程序(如由 ob_start()output_add_rewrite_var() 启动的处理程序)没有任何影响。

参数

enable

true 表示启用隐式刷新,false 表示禁用。

返回值

不返回值。

变更日志

版本 说明
8.0.0 enable 现在期望一个 bool 值;以前期望一个 int 值。

参见

  • flush() - 刷新系统输出缓冲区
  • ob_start() - 启用输出缓冲
  • ob_end_flush() - 刷新(发送)活动输出处理程序的返回值并关闭活动输出缓冲区

添加备注

用户贡献的备注 6 个备注

29
Pedro Gimeno
9 年前
注意,ob_implicit_flush 的名字具有误导性。尽管它的名字如此,这个函数并不适用于用户输出缓冲区,即其他 ob_* 函数使用的缓冲区。它不会自动执行 ob_flush()。它会自动执行 flush()。两者是不同的。

例如,以下脚本

<?php
ob_implicit_flush
();
for(
$i = 0; $i < 10; $i++)
{
echo
"$i\n";
sleep(1);
}
?>

将等效于以下脚本

<?php
for ($i = 0; $i < 10; $i++)
{
echo
"$i\n";
flush();
sleep(1);
}
?>

如果在 php.ini 中将 'output_buffering' 设置为 'on',那么该脚本将不会输出任何内容,直到结束。不幸的是,据我所知,没有办法在每次输出后执行隐式 ob_flush()。

如果你希望输出在生成时立即输出,一种解决方案是在脚本开头添加 ob_end_clean() 或 ob_end_flush()

<?php
ob_end_flush
();
ob_implicit_flush();
for (
$i = 0; $i < 10; $i++)
{
echo
"$i\n";
sleep(1);
}
?>

这将按顺序输出。这只有在你只想让一部分输出实时输出,而其他部分则被缓冲时才会出现问题。在这种情况下,由于没有函数可以每执行一次 ob_flush() 就执行一次隐式 ob_flush(),因此你需要显式调用它。例如,以下代码有效

<?php
ob_start
(); // 如果在 php.ini 中将 output_buffering 设置为 on,则不需要此行
ob_implicit_flush(); // 在每次 ob_flush() 后隐式调用 flush()

echo "This output is buffered.\n";
echo
"As is this.\n";

for (
$i = 0; $i < 10; $i++)
{
echo
"$i\n";
ob_flush();
sleep(1);
}
?>

还要注意,某些浏览器可能会等到它们获得一定数量的输出后才开始输出。有关详细信息,请参见 flush [ https://php.net/manual/en/function.flush.php ]。我使用 Firefox(Iceweasel 17.0)就是这种情况;除非我在开头输出 1024 字节,否则它不会开始输出。
3
damian at thebestisp dot dot dot com
8 年前
似乎有些人使用它来解决输出缓冲问题,而不是简单地将其关闭。对我来说,如果你有一个输出缓冲区,它就是有原因的,否则你就会要么做一些事情并使用 ob_flush() 或 ob_end_flush(),做一些事情,然后可能再次使用 ob_start()。
以下是如何在不抑制错误的情况下正确结束所有输出缓冲区(因为没有缓冲区)。如果你确实想要单级输出缓冲区,我已经包含了一个部分来实现这一点。
<?php
# 完全消除输出缓冲区
while (ob_get_level()) {ob_end_flush();}

# 确保如果这不是 CLI,我们有一级输出缓冲。
$notcli=(int)(PHP_SAPI!=='cli');
while ((
$diff=ob_get_level()-$notcli)!==0) {
if (
$diff>0) {ob_end_flush();}
else {
ob_start();}
}
7
rocca at start dot ca
16 年前
你也可以使用 Linux/Apache 获取无缓冲的输出,而无需在每一行后执行隐式刷新,只需在脚本开头调用

ob_implicit_flush(true);
ob_end_flush();

...即可。
6
Paul Yanchenko
18 年前
在控制台中,ob_implicit_flush() 还有另一个解决方法。是的,它不能按预期工作,但是你可以通过在 ob_start() 中指定 chunk_size=2 来获得类似的结果

<?php
ob_start
('ob_logstdout', 2);
?>

这将导致每出现一个新行(以 \n 结尾)都会刷新输出缓冲区。

希望这能帮到你。
5
calimero at Creatixnet dot com
21 年前
######### 注意 ##########

关于 ob_implicit_flush,存在一个 bug(或者至少是意外功能),这个问题已经在 PHP bugtracker 上讨论过

http://bugs.php.net/bug.php?id=23877
http://bugs.php.net/bug.php?id=16676

以下代码将无法正常工作

<?
// 这在 Linux 上无法正常工作。
ob_implicit_flush (1);
for($i=0;$i<10;$i++) {
echo "grrrrrrrrrr\n";
sleep(1);
}
?>

此问题出现在 Linux 版本的 PHP 中,包括所有 4.3.3 之前的 php4 版本(之后的版本还不确定),以及 php5 beta1。ob_implicit_flush 对命令行(控制台、CLI)脚本无效,不会有任何刷新,所有输出将在脚本执行结束后发送。

可以使用 ob_end_flush() 和 ob_flush 来解决这个问题,代码如下

<?
// 这段代码可以正常工作!
ob_end_flush();
for($i=0;$i<10;$i++) {
echo "yeah :-))))\n";
@ob_flush();
sleep(1);
}
?>

希望这些信息能帮到您。如果早点知道这些就好了...
2
mhumphrey at _spammenot_designvision dot com
20 年前
根据我的实验,使用 session.use_trans_sid=1 的会话将强制您的输出被缓冲,无论您是否设置了该选项。

我猜测这是因为 PHP 需要在您的输出中查找 URL,以便自动将 Session ID 添加到其中。它必须等到脚本输出完成才能开始替换,而不是“实时”进行替换。

当我注释掉 session_start() 行时,浏览器会持续输出。恢复该行后,页面只有在完全加载后才会显示。将 session.use_trans_sid 设置为 0 后,浏览器又开始持续输出。
To Top