【问题标题】:Why do I need `str_pad('',4096)` to make PHP flushing work?为什么我需要 `str_pad('',4096)` 来使 PHP 刷新工作?
【发布时间】:2013-01-29 01:54:40
【问题描述】:

例如,

这不起作用(Firefox 21、IE8):

<?php
function flush_buffers(){
    ob_end_flush();
    ob_flush();
    flush();
    ob_start();
}  
ob_start();
echo 'Text 1<br />';
flush_buffers();
Sleep(2);
echo 'Text 2<br />';
flush_buffers();
Sleep(2);
echo 'Text 3<br />';
flush_buffers();
Sleep(2);
echo 'Text 4<br />';
?>

但这一个有效:

<?php
function flush_buffers(){
    echo str_pad('',4096);
    ob_end_flush();
    ob_flush();
    flush();
    ob_start();
}  
ob_start();
echo 'Text 1<br />';
flush_buffers();
Sleep(2);
echo 'Text 2<br />';
flush_buffers();
Sleep(2);
echo 'Text 3<br />';
flush_buffers();
Sleep(2);
echo 'Text 4<br />';
?>

我在 Win XP SP3 上运行 PHP 5.4.11 VC9 和 Apache 2.4.3 (apacheLounge)。

【问题讨论】:

    标签: php flush


    【解决方案1】:

    一些浏览器包含自己的内部缓冲区,以便更有效地下载和显示,减少波动。在大多数情况下,此缓冲区为 4Kb,即 4096 字节。

    str_pad('',4096) 所做的是将 4,096 个空格写入输出。由于它是 HTML,因此这些空间会折叠成一个空间。

    总体而言,不应依赖此行为。浏览器是用来查看网页的,而不是混入控制台终端。

    另外,你为什么写&lt;/br&gt;?没有结束&lt;br&gt;标签,自闭版是&lt;br /&gt;

    【讨论】:

    • 大声笑,你是对的那些&lt;/br&gt;。代码不是我的,但我应该看到的。
    • “总的来说,不应依赖这种行为”。那么,我该怎么办,使用 AJAX?
    • 这完全取决于你想要做什么。 AJAX 可能是一种方法,但实际上我需要更多地了解您在做什么才能提出有效的建议。
    • 我希望 PHP 连接到有时很慢的主机(不是我的)来读取一些 xml 文件(每次它们不同,我无法存储它们)并使用 xpath 获取一些数据。我认为我可以使用flush 从第一个 xml 发送数据,而它还没有读取第二个。
    • 嗯...缓慢的服务器是一种痛苦的工作。不过,您曾经使用过航班搜索网站吗?他们有一个加载屏幕,告诉您这将是几分钟,通常伴随着有用的链接和信息,例如您可以在等待时查看的汽车租赁和酒店。有什么办法可以做类似的事情吗?
    【解决方案2】:

    除了指定您的浏览器版本之外,您还应该指定 PHP 运行的 Web 服务器。毕竟,这就是输出缓冲可能发生的地方。

    如果您阅读documentation on flush,您会发现这不是保证操作。有点像磁盘写入,即使您有库和操作系统合作,仍然有磁盘硬件(可能)缓冲它。只有最细致(因此几乎不可能移植)的方法才能奏效,甚至不能保证。

    编辑:哦,是的,浏览器(或地狱,一些路由器或介于两者之间的 TCP 堆栈)也可以做到。

    【讨论】:

      【解决方案3】:

      这是因为浏览器的渲染引擎在决定将内容渲染到屏幕时需要获取足够的数据。而需要多少数据是由浏览器决定的。

      【讨论】:

        【解决方案4】:

        对于慢速托管,请尝试以下操作:

        $totalUsers = count_users();
        
        echo 'There are ', $result['total_users'], ' total users<br />';
        foreach($result['avail_roles'] as $role => $count)
            echo ', ', $count, ' are ', $role, 's';
        echo '.';
        
        $batchSize = 25;
        $batchesCount = ceil($totalUsers['total_users'] / $batchSize);
        $Users = array();
        for ($count = 0; $count < $batchesCount; $count++) {
        $args = array('number' => $batchSize, 'offset' => $count * $batchSize);
            $batchNewUsers = get_users($args);
            $Users = array_merge($Users, $batchNewUsers);
            sleep(1); # reduce load
            echo '.'.str_pad(' ',4096);# keep alive
        }
        
        echo '<br />All done.';
        

        否则,您最好直接查询数据库,或者先获取 ID 并按 ID 查询每个: https://wordpress.stackexchange.com/questions/231003/how-to-get-list-of-all-users-there-metadata

        【讨论】:

          猜你喜欢
          • 2017-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-10
          • 1970-01-01
          • 2020-12-03
          • 2015-03-12
          相关资源
          最近更新 更多