打印过程实时输出

时间:2012-01-06 22:23:27

标签: php apache

我在Windows 7 x64系统上使用PHP 5.3.4和Apache 2.2.17。我希望我的PHP页面能够实时向用户的浏览器输出system调用的结果。为此,我在php.ini中配置了output_buffering=Off并创建了此代码:

<?php
ob_implicit_flush(true);
ob_end_flush();
system('ping -n 10 www.google.com');
?>

ping的结果是实时打印的,但是我的页面顶部也出现了PHP诊断错误和callstack:

Notice: ob_end_flush() [ref.outcontrol]: failed to delete and flush buffer. No buffer to delete or flush in index.php on line 3

我需要做些什么来纠正或抑制此错误?

更新 如果我将ob_end_flush()更改为$a = 1/0;,我会收到类似的错误,并且输出在所有浏览器中都是实时的。打印异常的方式是否有效?

5 个答案:

答案 0 :(得分:6)

某些web 浏览器在开始呈现页面之前缓冲前x个字节,在某些条件下。

首先尝试输出大量空白

答案 1 :(得分:3)

我有一个可行的解决方案,但它不具备性能且 icky 。我抛出异常,但隐藏了异常对话框。

<?php
    ob_implicit_flush(true);

    // Something about the way exceptions are thrown causes Firefox and Chrome 
    // to be able to display the results of the system call in real-time rather
    // than having to wait for the call to complete. So, I just hide the 
    // exception message. IE9 works with or without this.
    echo "<div style=\"display:none\">";
    $a = 1/0;
    echo "</div>";

    echo "<pre>";
    system('ping -n 5 www.google.com');
    echo "</pre>";
?>

要自动滚动到页面底部,我添加一些javascript:

<html><head>
<script language="javascript">
var int = self.setInterval("window.scrollBy(0,1000);", 200);
</script>
</head>
<body>
<?php
    // insert above php code here
    // stop scrolling when the execution finishes
    echo '<script language="javascript">int = window.clearInterval(int);</script>';
?>
</body>
</html>

修改

@Chris的答案显示了一个更好的解决方案。

echo '<div style="display:none">';
for ($a = 0; $a < 768; $a++)
    echo ' ';
echo '</div>';

答案 2 :(得分:1)

只需添加此项即可刷新缓冲区:

    if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) {
       echo "<div style=\"display:none\">";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";    
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";    
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
          echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
       echo "</div>";
    }

它必须在循环内。或者在两个输出之间,你需要实时显示。

这是速记技巧:

添加:

if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) {
   echo "<div style=\"display:none\"></div>";                    
}

答案 3 :(得分:0)

在您的代码中,错误很容易解释。

你在第3行调用ob_end_flush(),但是(如错误所示),没有输出要刷新。本质上,第3行是没用的,因为没有输出,所以删除该行将修复错误。如果将其合并到一个更大的文件中,您可能需要保留ob_end_flush(),因为某些输出可能已被捕获。

编辑:因为你需要冲洗它,所以:

a:将ob_start();添加到文件顶部。

b:将ob_end_flush();替换为flush();

EDIT2:由于第一个似乎不起作用,这是我能提供的最好的:How to echo output in real time, (before script finishes)?

答案 4 :(得分:0)

ob_end_flush()刷新php输出缓冲区,并需要使用ob_start()创建的活动输出缓冲区。

我想你只想调用flush()将数据发送到客户端。

<?php
ob_implicit_flush(true);
flush();
system('ping -n 10 www.google.com');
?>