如何在每次“echo”调用后刷新输出?

发布于 2024-09-07 17:03:19 字数 243 浏览 13 评论 0 原文

我有一个 php 脚本,它只向客户端生成日志。
当我回显某些内容时,我希望将其即时传输到客户端。
(因为当脚本正在处理时,页面是空白的)
我已经尝试过 ob_start()ob_flush(),但它们不起作用。

最好的解决方案是什么?

PS:在 echo 调用末尾添加刷新有点脏...

编辑:答案都不起作用,PHP 或 Apache 故障?

I have a php script that only produces logs to the client.
When I echo something, I want it to be transferred to client on-the-fly.
(Because while the script is processing, the page is blank)
I had already played around with ob_start() and ob_flush(), but they didn't work.

What's the best solution?

PS: it is a little dirty to put a flush at the end of the echo call...

EDIT: Neither the Answers worked, PHP or Apache Fault?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

梦言归人 2024-09-14 17:03:50

https://stackoverflow.com/a/48914827/7485823

$input  = "Hello world";
echo str_pad($input,  1024*64, " ");

一个可爱且实用的解决方案 - 有一个陷阱:很多输出中有多余的空白。

它在

  • Chrome + Edge 中生成:生成以“...”作为截断结尾的 10,005 个字符串
  • Firefox:65540 个字符串(原文如此)

str_repeat 更改为 str_pad 可最大限度地减少该问题。但是将填充字符从空白“”更改为空“\x00”似乎可以进一步减少问题。

$input  = "Hello world";
echo str_pad($input,  1024*64, "\x00");

在 Chrome、Edge 和 Firefox 中生成 15 个字符的字符串,

我无法判断该字符串在哪里被截断。但是服务器上的缓存已满,并且输出已发送,并且您的输出不会因冗余空白的威胁而混乱。

https://stackoverflow.com/a/48914827/7485823

$input  = "Hello world";
echo str_pad($input,  1024*64, " ");

A lovely and practically solution - with a a catch: A lot of redundant blanks in your output.

It produces in

  • Chrome + Edge: Produces a 10,005 character string ending with "…" as truncation
  • Firefox: A 65540 character string (sic)

Changing str_repeat to str_pad minimizes the issue. But changing the padding character from blank " " to null "\x00" seems the reduce the problem even further.

$input  = "Hello world";
echo str_pad($input,  1024*64, "\x00");

Produces in Chrome, Edge and Firefox a 15 character string

I cannot tell where the string is truncated. But the cache on the server is filled and the output is send AND your output is not cluttered by a menace of redundant blanks.

俯瞰星空 2024-09-14 17:03:49

对我来说最好的解决方案(也希望对你来说):

在 php 的开头:

header('Content-Encoding: none');
ob_end_flush();
ob_implicit_flush(1);

然后,只有这个在你的循环中:

echo str_pad('',4096);

示例:

<?php

  header('Content-Encoding: none');
  ob_end_flush();
  ob_implicit_flush(true);

  for($i = 0; $i < 100;$i++){
    $txt = "Number is: " . $i . "<br />";
    echo str_pad($txt,4096);
    sleep(1);
  }

?>

Best solution for me (and hope for you):

At the beginning of php:

header('Content-Encoding: none');
ob_end_flush();
ob_implicit_flush(1);

Then, only this in your loop:

echo str_pad('',4096);

Example:

<?php

  header('Content-Encoding: none');
  ob_end_flush();
  ob_implicit_flush(true);

  for($i = 0; $i < 100;$i++){
    $txt = "Number is: " . $i . "<br />";
    echo str_pad($txt,4096);
    sleep(1);
  }

?>
凹づ凸ル 2024-09-14 17:03:47

情况有点复杂,但并非绝望,因为即使在其他阶段,输出也会因不同原因而被缓冲,例如 gzip、Apache、PHP(快速)GCI 与 CLI(来自命令行 $ php -a) - 而且也有不同的浏览器!

这也是为什么 PHP 确实将其评为“不是错误”,所以更多类似“rtfm”的内容,仍然可能值得改进 - 这意味着,您应该(必须?)看看全部 手册的相关部分,不仅仅是针对某一单一功能?!我知道,这可能会让人筋疲力尽,但如果您不了解系统,那么在一段时间内的微小差异和微小变化都会让您失败 - 而且很多“does为我工作”——评论表明了这一点。

PHP手册中经常有通用章节,例如输出缓冲,它也试图解释系统和用户级缓冲区之间的差异!必读!

虽然对上面的很多答案和评论做了一些具体的评论,但恐怕我仍然不被允许发表评论......

所以只有一些基本提醒根据我的“研究”(学习)结果,如果您至少深入研究了您的设置并阅读了大部分 PHP 手册:

请始终查看您的当前设置,由 php.ini 和/或 .htaccess 等部分组成;
例如使用 // 但不要在公共/生产系统上保留对该信息的访问权限!

例如我对 PHP 8.2.17 的默认设置是...
output_buffering = 4096

(剧透:其他版本的 PHP 可能使用整数而不是布尔值 - 请务必查看您版本的手册 - 它总是能给人带来惊喜)

  • 设置 output_buffering 为一个值将把 user -level bufferingob_start() 一样打开,
  • 我无法通过 var_dump( ini_set('output_buffering', 0) ); 在脚本级别关闭它- 导致 false 指示失败,无法设置
  • 缓冲对于性能或更改(“重写”)以及丢弃已经生成的输出都有好处(考虑用于在发生错误时传送图像的标头)错误,需要不同的标头),
  • 因此要在脚本中的某个点停止缓冲,您通常可能需要 ob_end_flush() 来发送当前内容,并结束缓冲 - 而不是“干净” (丢弃缓冲区)版本?
  • 输出缓冲还可以有更多级别(在用户“ob_...”侧)
  • 最低(最后边界)是 PHP 的独立(!) 系统级,由 flush()
  • 和明显误导性的 ob_implicit_flush() 控制> (默认参数值为 bool $enable = true ),它会在代码块的每一位上自动刷新(系统缓冲区!),
  • 但我们可能仍然需要一点缓冲(为了网络和系统性能?!)并且通过显式使用flush()可以获得更多的输出控制

好吧,你是对的,我应该展示更多内容:

免责声明:使用(标准)'text/html'而不带s.th 。就像 最终会进入“Quirks-Mode”,这将提供另一层惊喜 - 但做喜欢的事;)

<?php
header( 'Content-type: text/plain; charset=utf-8' );
//header( 'Content-type: text/html; charset=utf-8' );
//echo '<!DOCTYPE html>',PHP_EOL;

ob_end_flush(); // flush user buffer to deliver header data and end user-level buffering
ob_implicit_flush(true); // automatically flush system buffer on every code block

echo str_repeat(PHP_EOL, 5); // I like space

for( $i=10; $i>0; $i-- ){
  echo $i,'  ';
  //flush(); // now done by _implicit_ 
  sleep(1);
}
echo '*',PHP_EOL;
// final flushing always done by end of script
?>

对我有用:)好吧,即使不明显,所以祝你好运和耐力!
长寿和繁荣 \\//-
BR 克劳斯

The situation is a little complex, but not hopeless, cause output will be buffered for different reasons, even at other stages, e.g. gzip, Apache, PHP (Fast)GCI vs. CLI (from commandline $ php -a) - and there are different browsers, too!

That's also why PHP did rate it as "NOT a bug", so more something like "rtfm", which still may be worth an improvement -- meaning, you should (must?) have a look at all related parts of the manual, not only at that for one single function?! I know, this might feel exhausting, but if you don't understand the system, also small differences and also small changes during time will make you fail - and the lot of "does not work for me"-comments show that.

There are often general chapters in the PHP manual, e.g. Output Buffering, which also tries to explain the differences between System and User-Level Buffers! A MUST READ!

Although having some specific remarks on a lot of answers and comments above, I'm afraid, I'm still not allowed to comment...

So just a few basic reminders from my "research" (learning) results, if at least you dig into your setting and have read most of the PHP manual:

Always have a look at your current settings, by php.ini and/or .htaccess and other parts;
e.g. using <?php phpinfo(); ?> // but do not leave access to that info on a public/productive system!!

For example my default with PHP 8.2.17 says ...
output_buffering = 4096

(spoiler: other versions of PHP may use integers instead of bools - always have a look at your version's manual - it's always good for a surprise)

  • setting output_buffering to a value will turn user-level buffering ON like a ob_start()
  • which I can not switch off at script-level via var_dump( ini_set('output_buffering', 0) ); - results in false indicating failure, can not be set
  • buffering is good for performance or for changing ("rewrite") and for discarding already produced output (think of a header for shipping an image in case of an error, needing a different header)
  • so to stop the buffering at a point in script, you may typically want a ob_end_flush() to send the current content, and end-ing buffering - not the 'clean' (discard buffer) version?
  • output buffering can have also more levels (on the user "ob_..." side)
  • the lowest (last frontier) is PHP's independent(!) system-level, controlled by flush()
  • and by the ob-vious misleading named ob_implicit_flush() (the default argument value is bool $enable = true), which flushes (the System Buffer!) automatically on every bit of code block
  • but we may still want a little buffering (for network and system performance?!) and would gain more output control with explicit use of flush()

Well, you are right, I should show something more:

Disclaimer: Using (standard) 'text/html' without s.th. like <!DOCTYPE html> will end up in "Quirks-Mode", what will provide another level of surprise - but do what you like ;)

<?php
header( 'Content-type: text/plain; charset=utf-8' );
//header( 'Content-type: text/html; charset=utf-8' );
//echo '<!DOCTYPE html>',PHP_EOL;

ob_end_flush(); // flush user buffer to deliver header data and end user-level buffering
ob_implicit_flush(true); // automatically flush system buffer on every code block

echo str_repeat(PHP_EOL, 5); // I like space

for( $i=10; $i>0; $i-- ){
  echo $i,'  ';
  //flush(); // now done by _implicit_ 
  sleep(1);
}
echo '*',PHP_EOL;
// final flushing always done by end of script
?>

Works for me :) well, even not obvious, so wish you good luck and endurance!
Live long and prosper \\//-
BRs Klaus

好倦 2024-09-14 17:03:46

我迟到了讨论,但我读到很多人都在说附加flush();每个代码的末尾看起来很脏,但它们是对的。

最佳解决方案是禁用 deflate、gzip 以及来自 Apache、中间处理程序和 PHP 的所有缓冲。然后在你的 php.ini 中你应该有:

            output_buffering = Off
            zlib.output_compression = Off
            implicit_flush = Off

临时解决方案 是在你的 php.ini 中包含这个如果你可以用flush()解决你的问题;但你觉得到处放它又脏又丑。

implicit_flush = On

如果你只把它放在你的 php.ini 上面,你不需要把lush();不再在你的代码中。

I'm late to the discussion but I read that many people are saying appending flush(); at the end of each code looks dirty, and they are right.

Best solution is to disable deflate, gzip and all buffering from Apache, intermediate handlers and PHP. Then in your php.ini you should have:

            output_buffering = Off
            zlib.output_compression = Off
            implicit_flush = Off

Temporary solution is to have this in your php.ini IF you can solve your problem with flush(); but you think it is dirty and ugly to put it everywhere.

implicit_flush = On

If you only put it above in your php.ini, you don't need to put flush(); in your code anymore.

鱼忆七猫命九 2024-09-14 17:03:46

这是我的代码:(适用于 PHP7)

private function closeConnection()
{
    @apache_setenv('no-gzip', 1);
    @ini_set('zlib.output_compression', 0);
    @ini_set('implicit_flush', 1);

    ignore_user_abort(true);
    set_time_limit(0);

    ob_start();
    // do initial processing here
    echo json_encode(['ans' => true]);

    header('Connection: close');
    header('Content-Length: ' . ob_get_length());
    ob_end_flush();
    ob_flush();
    flush();
}

This is my code: (work for PHP7)

private function closeConnection()
{
    @apache_setenv('no-gzip', 1);
    @ini_set('zlib.output_compression', 0);
    @ini_set('implicit_flush', 1);

    ignore_user_abort(true);
    set_time_limit(0);

    ob_start();
    // do initial processing here
    echo json_encode(['ans' => true]);

    header('Connection: close');
    header('Content-Length: ' . ob_get_length());
    ob_end_flush();
    ob_flush();
    flush();
}
提赋 2024-09-14 17:03:45

请注意,如果您在某些共享托管网站(例如 Dreamhost)上,则在不通过不同路由的情况下根本无法禁用 PHP 输出缓冲:

更改输出缓冲区缓存 如果您使用 PHP FastCGI,则 PHP
函数flush()、ob_flush()和ob_implicit_flush()不会
按预期运行。默认情况下,输出在更高级别进行缓冲
比 PHP (具体来说,通过 Apache 模块 mod_deflate 来实现)
形式/功能与 mod_gzip 类似)。

如果您需要无缓冲输出,则必须使用 CGI(而不是
FastCGI)或联系支持人员请求禁用 mod_deflate
为您的网站。

https://help.dreamhost.com/hc/en- us/articles/214202188-PHP-概述

Note if you are on certain shared hosting sites like Dreamhost you can't disable PHP output buffering at all without going through different routes:

Changing the output buffer cache If you are using PHP FastCGI, the PHP
functions flush(), ob_flush(), and ob_implicit_flush() will not
function as expected. By default, output is buffered at a higher level
than PHP (specifically, by the Apache module mod_deflate which is
similar in form/function to mod_gzip).

If you need unbuffered output, you must either use CGI (instead of
FastCGI) or contact support to request that mod_deflate is disabled
for your site.

https://help.dreamhost.com/hc/en-us/articles/214202188-PHP-overview

秋心╮凉 2024-09-14 17:03:44

试试这个:

while (@ob_end_flush());      
ob_implicit_flush(true);

echo "first line visible to the browser";
echo "<br />";

sleep(5);

echo "second line visible to the browser after 5 secs";

请注意,这样您实际上禁用了当前脚本的输出缓冲区。我想你可以用 ob_start() 重新启用它(我不确定)。

重要的是,通过像上面那样禁用输出缓冲区,您将无法再使用 header() 函数重定向 php 脚本,因为每次脚本执行 php 只能发送一次 http 标头。
不过,您可以使用 JavaScript 进行重定向。只需让您的 php 脚本回显以下几行:

        echo '<script type="text/javascript">';
        echo 'window.location.href="'.$url.'";';
        echo '</script>';
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
        echo '</noscript>'; 
        exit;

Try this:

while (@ob_end_flush());      
ob_implicit_flush(true);

echo "first line visible to the browser";
echo "<br />";

sleep(5);

echo "second line visible to the browser after 5 secs";

Just notice that this way you're actually disabling the output buffer for your current script. I guess you can reenable it with ob_start() (i'm not sure).

Important thing is that by disabling your output buffer like above, you will not be able to redirect your php script anymore using the header() function, because php can sent only once per script execution http headers.
You can however redirect using javascript. Just let your php script echo following lines when it comes to that:

        echo '<script type="text/javascript">';
        echo 'window.location.href="'.$url.'";';
        echo '</script>';
        echo '<noscript>';
        echo '<meta http-equiv="refresh" content="0;url='.$url.'" />';
        echo '</noscript>'; 
        exit;
不知在何时 2024-09-14 17:03:42

有时,问题来自 Apache 设置。 Apache 可以设置为 gzip 输出。
在文件 .htaccess 中,您可以添加例如:

SetEnv no-gzip 1

Sometimes, the problem come from Apache settings. Apache can be set to gzip the output.
In the file .htaccess you can add for instance :

SetEnv no-gzip 1
仄言 2024-09-14 17:03:41

防病毒软件也可能会干扰输出刷新。就我而言,卡巴斯基反病毒软件 2013 在将数据块发送到浏览器之前会保留数据块,即使我使用的是公认的解决方案。

Anti-virus software may also be interfering with output flushing. In my case, Kaspersky Anti-Virus 2013 was holding data chunks before sending it to the browser, even though I was using an accepted solution.

不必在意 2024-09-14 17:03:40

这对我来说效果很好(Apache 2.4/PHP 7.0):

@ob_end_clean();
echo "lorem ipsum...";
flush();
sleep(5);
echo "<br>dolor...";
flush();
sleep(5);
echo "<br>sit amet";

This works fine for me (Apache 2.4/PHP 7.0):

@ob_end_clean();
echo "lorem ipsum...";
flush();
sleep(5);
echo "<br>dolor...";
flush();
sleep(5);
echo "<br>sit amet";
じ违心 2024-09-14 17:03:39

正确使用的函数是flush()

<html>
<body>
<p>
Hello! I am waiting for the next message...<br />
<?php flush(); sleep(5); ?>
I am the next message!<br />
<?php flush(); sleep(5); ?>
And I am the last message. Good bye.
</p>
</body>
</html>

请注意,IE 存在一个“问题”,它仅在至少 256 字节时输出刷新的内容,因此页面的第一部分至少需要 256 字节。

The correct function to use is flush().

<html>
<body>
<p>
Hello! I am waiting for the next message...<br />
<?php flush(); sleep(5); ?>
I am the next message!<br />
<?php flush(); sleep(5); ?>
And I am the last message. Good bye.
</p>
</body>
</html>

Please note that there is a "problem" with IE, which only outputs the flushed content when it is at least 256 byte, so your first part of the page needs to be at least 256 byte.

蓝梦月影 2024-09-14 17:03:37

我也有类似的事情要做。 在我的例子中,使用

// ini_set("output_buffering", 0);  // off 
ini_set("zlib.output_compression", 0);  // off
ini_set("implicit_flush", 1);  // on   

确实使输出频繁刷新。

但我必须在特定点(在我运行的循环中)刷新输出,因此将两者

ob_flush();
flush();

一起使用对我来说很有效。

我没能做到
关闭“output_buffering”
ini_set(...),只好直接转
在 php.ini 中,phpinfo() 显示其设置
关闭时“没有价值”,是这样吗
普通的? .

I had a similar thing to do. Using

// ini_set("output_buffering", 0);  // off 
ini_set("zlib.output_compression", 0);  // off
ini_set("implicit_flush", 1);  // on   

did make the output flushing frequent in my case.

But I had to flush the output right at a particular point(in a loop that I run), so using both

ob_flush();
flush();

together worked for me.

I wasn't able to
turn off "output_buffering" with
ini_set(...), had to turn it directly
in php.ini, phpinfo() shows its setting
as "no value" when turned off, is that
normal? .

晨曦慕雪 2024-09-14 17:03:36
header( 'X-Accel-Buffering: no' );
header( 'Content-Type: text/html; charset=utf-8' );

echo 'text to display';
echo '<span style="display: none;">' . str_repeat ( ' ', 4096 ) . '</span>';
flush();
usleep( 10 );
header( 'X-Accel-Buffering: no' );
header( 'Content-Type: text/html; charset=utf-8' );

echo 'text to display';
echo '<span style="display: none;">' . str_repeat ( ' ', 4096 ) . '</span>';
flush();
usleep( 10 );
岁月静好 2024-09-14 17:03:34

不经常提及的一件事是 gzip 压缩,由于各种托管环境中的详细信息而保持打开状态。

这是一种现代方法,使用 PHP-FPM 作为快速 CGI,不需要 .htaccess 重写规则或环境变量:

在 php.ini 或 .user.ini 中:

output_buffering = 0
zlib.output_compression = 0
implicit_flush = true
output_handler = 

在 PHP 脚本中:

header('Content-Encoding: none'); // Disable gzip compression
ob_end_flush(); // Stop buffer
ob_implicit_flush(1); // Implicit flush at each output command

请参阅 此评论官方 PHP 文档,用于 ob_end_flush() 需求。

One thing that is not often mentionned is gzip compression that keeps turned ON because of details in various hosting environments.

Here is a modern approach, working with PHP-FPM as Fast CGI, which does not need .htaccess rewrite rule or environment variable :

In php.ini or .user.ini :

output_buffering = 0
zlib.output_compression = 0
implicit_flush = true
output_handler = 

In PHP script :

header('Content-Encoding: none'); // Disable gzip compression
ob_end_flush(); // Stop buffer
ob_implicit_flush(1); // Implicit flush at each output command

See this comment on official PHP doc for ob_end_flush() need.

阳光的暖冬 2024-09-14 17:03:33

为什么不创建一个回显函数,如下所示:

function fecho($string) {
 echo $string;
 ob_flush();
}

Why not make a function to echo, like this:

function fecho($string) {
 echo $string;
 ob_flush();
}
坠似风落 2024-09-14 17:03:31

你想要的是 flush 方法。
例子:

echo "log to client";
 flush();

what you want is the flush method.
example:

echo "log to client";
 flush();
总攻大人 2024-09-14 17:03:30

刷新看似不起作用是自动字符集检测的副作用。

浏览器在知道显示内容的字符集之前不会显示任何内容,如果您不指定字符集,它需要尝试猜测它。问题在于,如果没有足够的数据,它就无法做出好的猜测,这就是为什么浏览器似乎在显示任何内容之前需要填充这个 1024 字节(或类似)的缓冲区。

因此,解决方案是确保浏览器不必猜测字符集。

如果您要发送文本,请添加 '; charset=utf-8' 添加到其内容类型,如果是 HTML,则将字符集添加到适当的元标记。

Flushing seemingly failing to work is a side effect of automatic character set detection.

The browser will not display anything until it knows the character set to display it in, and if you don't specify the character set, it need tries to guess it. The problem being that it can't make a good guess without enough data, which is why browsers seem to have this 1024 byte (or similar) buffer they need filled before displaying anything.

The solution is therefore to make sure the browser doesn't have to guess the character set.

If you're sending text, add a '; charset=utf-8' to its content type, and if it's HTML, add the character set to the appropriate meta tag.

心在旅行 2024-09-14 17:03:29

对于 2018 年即将到来的人:

唯一的解决方案对我有用:

<?php

    if (ob_get_level() == 0) ob_start();
    for ($i = 0; $i<10; $i++){

        echo "<br> Line to show.";
        echo str_pad('',4096)."\n";    

        ob_flush();
        flush();
        sleep(2);
    }

    echo "Done.";

    ob_end_flush();
?>

保留“4096”部分非常重要,因为它似乎“填充”了缓冲区......

For those coming in 2018:

The ONLY Solution worked for me:

<?php

    if (ob_get_level() == 0) ob_start();
    for ($i = 0; $i<10; $i++){

        echo "<br> Line to show.";
        echo str_pad('',4096)."\n";    

        ob_flush();
        flush();
        sleep(2);
    }

    echo "Done.";

    ob_end_flush();
?>

and its very important to keep de "4096" part because it seems that "fills" the buffer...

倒数 2024-09-14 17:03:27

这就是我发现的。

Flush 在 Apache 的 mod_gzip 或 Nginx 的 gzip 下无法工作,因为从逻辑上讲,它正在对内容进行 gzip 压缩,并且要做到这一点,它必须缓冲内容以对其进行 gzip。任何类型的 Web 服务器 gzip 压缩都会影响这一点。简而言之,在服务器端我们需要禁用 gzip 并减小 fastcgi 缓冲区大小。所以:

  • 在 php.ini 中:

    output_buffering = 关闭
    
    zlib.output_compression = 关闭
    
  • 在 nginx.conf 中:

    gzip 关闭;
    
    proxy_buffering 关闭;
    

手头还有这些行,特别是如果您无权访问 php.ini:

@ini_set('zlib.output_compression',0);

@ini_set('implicit_flush',1);

@ob_end_clean();

set_time_limit(0);

最后,如果您有,请注释下面的代码:

ob_start('ob_gzhandler');

ob_flush();

PHP test代码:

ob_implicit_flush(1);

for ($i=0; $i<10; $i++) {
    echo $i;

    // this is to make the buffer achieve the minimum size in order to flush data
    echo str_repeat(' ',1024*64);

    sleep(1);
}

So here's what I found out.

Flush would not work under Apache's mod_gzip or Nginx's gzip because, logically, it is gzipping the content, and to do that it must buffer content to gzip it. Any sort of web server gzipping would affect this. In short, at the server side we need to disable gzip and decrease the fastcgi buffer size. So:

  • In php.ini:

    output_buffering = Off
    
    zlib.output_compression = Off
    
  • In nginx.conf:

    gzip  off;
    
    proxy_buffering  off;
    

Also have these lines at hand, especially if you don't have access to php.ini:

@ini_set('zlib.output_compression',0);

@ini_set('implicit_flush',1);

@ob_end_clean();

set_time_limit(0);

Last, if you have it, comment the code bellow:

ob_start('ob_gzhandler');

ob_flush();

PHP test code:

ob_implicit_flush(1);

for ($i=0; $i<10; $i++) {
    echo $i;

    // this is to make the buffer achieve the minimum size in order to flush data
    echo str_repeat(' ',1024*64);

    sleep(1);
}
蓝礼 2024-09-14 17:03:26

编辑:

我正在阅读手册页上的评论,并发现一个 bug 表明 ob_implicit_flush 不起作用,以下是它的解决方法:

ob_end_flush();

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_start();

如果这不起作用,那么甚至可能发生的情况是在服务器建立了足够的字符来发送它认为值得发送的数据包之前,客户端不会从服务器接收数据包。


旧答案:

您可以使用ob_implicit_flush 这将告诉输出缓冲关闭缓冲一段时间:

ob_implicit_flush(true);

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_implicit_flush(false);

Edit:

I was reading the comments on the manual page and came across a bug that states that ob_implicit_flush does not work and the following is a workaround for it:

ob_end_flush();

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_start();

If this does not work then what may even be happening is that the client does not receive the packet from the server until the server has built up enough characters to send what it considers a packet worth sending.


Old Answer:

You could use ob_implicit_flush which will tell output buffering to turn off buffering for a while:

ob_implicit_flush(true);

# CODE THAT NEEDS IMMEDIATE FLUSHING

ob_implicit_flush(false);
一抹淡然 2024-09-14 17:03:24

我遇到了同样的问题,并且手册中发布的示例之一有效。必须将字符集指定为此处已提到的海报之一。 http://www.php.net/manual/en/function .ob-flush.php#109314

header( 'Content-type: text/html; charset=utf-8' );
echo 'Begin ...<br />';
for( $i = 0 ; $i < 10 ; $i++ )
{
    echo $i . '<br />';
    ob_flush();
    flush();
    sleep(1);
}
echo 'End ...<br />';

I've gotten the same issue and one of the posted example in the manual worked. A character set must be specified as one of the posters here already mentioned. http://www.php.net/manual/en/function.ob-flush.php#109314

header( 'Content-type: text/html; charset=utf-8' );
echo 'Begin ...<br />';
for( $i = 0 ; $i < 10 ; $i++ )
{
    echo $i . '<br />';
    ob_flush();
    flush();
    sleep(1);
}
echo 'End ...<br />';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文