【问题标题】:Disabling output buffering in PHP在 PHP 中禁用输出缓冲
【发布时间】:2012-04-01 10:34:13
【问题描述】:

我有一个任务对象,在 __deconstruct() 上,它的目的是在页面的其余部分已经加载后运行一些较长的清理任务。不幸的是,它会缓冲输出,直到任务完成后才会发送它(任务中没有打印任何内容)。

我已经阅读了http://www.php.net/flush 并尝试了那里的所有建议。显然我已经尝试在 php.ini 中禁用 output_buffering。我已禁用 deflate_module,zlib 压缩已关闭,没有 mod_gzip。调用 flush() 或 ob_flush() 无效,启用implicit_flush 也无效。

我只是在 Windows Server 2008 R2 下运行 XAMPP(当前为 apache 2.2.17,php 5.3.4)。 PHP 正在作为一个模块运行。

是的,我可以设置一些小的 AJAX hack 来运行任务管理器,甚至设置一个计划任务来运行这个特定的任务,但是输出缓冲在其他地方也是一个问题。只是希望它有时消失。

从一个类似的帖子中,有人建议看看以下内容会做什么:

<?php
while (TRUE)
{
    echo 'x';
    flush();
    sleep(1);
}
?>

正如预期的那样,页面在达到最大执行时间之前什么都不显示,此时它会刷新缓冲区。

这变得非常令人沮丧。任何人都知道什么仍然会导致它缓冲?

【问题讨论】:

  • 您能否确认输出仍在缓冲,而浏览器只是不显示任何内容(例如,IE 在接收到一定数量的字节之前不会显示任何内容)?
  • 这个函数php.net/manual/en/function.ob-get-level.php是否返回0?
  • 如果有帮助可以试试吗in3.php.net/manual/en/function.ob-end-flush.php
  • 我尝试了多个浏览器,所以我认为这不是问题所在。当然,经过实际测试,事实证明确实如此。 ob_get_level() 返回 0,因为这不是问题。

标签: php apache xampp buffering


【解决方案1】:

您只发送少量数据。浏览器有自己的缓冲区,可以基于字节数、接收到的元素或其他内容。

简而言之,您对此无能为力。缓冲发生在客户端,而不是服务器端。您可以尝试在xs 之前发送更多数据。

您可以通过使用Wireshark 或类似的方式嗅探服务器和浏览器之间的连接的数据包来证明这一点。

【讨论】:

  • 好吧,我想说我之前发送了相当多的数据,但是在将其更改为 for($i=0;$i';sleep(1)},它输出就好了。我想唯一的解决方法是发送更多数据以强制浏览器显示它。可能不太理想。不过谢谢。我一直在检查我的脚本和配置,这让我发疯了。
  • IE 以这一点而闻名。我在刷新之前通过发送大约 1000 个空格来欺骗 IE。因为 HTML 混合了空格,所以这无关紧要。
【解决方案2】:

嗯,有趣的是我在其他地方使用了一段代码,它按预期工作......

https://stackoverflow.com/a/9728519/632951

<?php
echo str_repeat('fillerbytes',20*1024/strlen('fillerbytes'));
echo '<body style="font-size:6px;font-family:arial;">';
echo str_repeat('<br>',2);
    for($i=1; $i<=5000; $i++){
        echo $i . ' ';
        ob_flush();
        flush();
        usleep(2000); // 2 ms each = 10s total
    }
?>

观察我的服务器数量增加到 5000 http://atwebresults.com/texttest/new.php

(不适用于一些免费主机,例如 freehostingeu.com。)

【讨论】:

  • 是的,这行得通。不幸的是,这只是因为它发送的数据比我想发送的要多得多。将迭代之间的时间更改为 1 秒而不是 0.001 秒会导致不想要的行为返回。
  • 这让我很开心。我认为它之所以有效是因为使用了 ob_flush();而不是 flush();
  • 是因为发送的数据量,而不是ob_flush()。原始示例即使添加 ob_flush() 也会失败,或者将迭代之间的时间更改为 1 秒而不是像现在这样的千分之一秒时失败。
  • @TimWick,请注意,只有在没有中间人缓冲响应的情况下,才能向最终用户流式传输。 另请参阅 archive.is/e1jB#selection-1725.262-1725.307
  • @TimWickstrom,您使用哪家托管公司?
猜你喜欢
  • 2010-09-11
  • 1970-01-01
  • 2011-04-20
  • 2012-08-23
  • 1970-01-01
相关资源
最近更新 更多