2012-01-06 69 views
5

我在Windows 7 x64系统上使用PHP 5.2.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'); 
?> 

平的结果打印实时的,但在顶我也得到一个PHP诊断错误和调用堆栈我的页面上写着:

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;我收到了类似的错误,并且输出在所有浏览器实时。打印异常的方式会导致这种情况发生吗?

+2

删除'ob_end_flush()函数;' – Grexis 2012-01-06 22:25:26

+0

如果我删除或用@抑制,输出不再是实时的Chrome 16或Firefox 10.(虽然它在IE9中工作) – PaulH 2012-01-06 22:29:14

+0

这很奇怪,但请参阅下面的答案。 – Grexis 2012-01-06 22:36:12

回答

6

某些Web浏览器缓冲第一x字节便开始呈现页面之前,在一定条件下。

尝试只输出大量的空格第一

+0

是的。这是问题。谢谢! – PaulH 2012-01-09 18:45:05

+2

我不得不正确回应894个字符到浏览器以启用实时输出。测试Firefox 21和IE 8。 – Clarkey 2013-06-08 11:28:49

0

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

您在第3行呼叫ob_end_flush(),但(如错误所述),没有输出要刷新。实质上,第3行是无用的,因为没有输出已发送,所以删除该行将修复错误。如果将其合并到较大的文件中,则可能需要保留ob_end_flush(),因为某些输出可能已被捕获。

编辑:既然你需要刷新它,无论是:

答:加入ob_start();到文件的顶部。

B:与flush();

EDIT2更换ob_end_flush();:因为第一似乎没有工作,这是最好的,我可以提供:How to echo output in real time, (before script finishes)?

+0

如果我将其删除,Chrome 16或Firefox 10中的输出将不再实时。(尽管它在IE9中可以正常工作) – PaulH 2012-01-06 22:37:22

+0

每次编辑 - 使用更改A,它不会在任何浏览器中实时显示。随着变化B它只是在IE9实时。 – PaulH 2012-01-06 22:40:45

+0

@PaulH看看我链接的问题的答案。类似的,可能是同样的问题。 – Grexis 2012-01-06 22:52:44

0

ob_end_flush()函数刷新PHP的输出缓冲,并要求一个使用ob_start()创建的活动输出缓冲区。

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

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

使用此代码,Chrome 16或Firefox 10中的输出不是实时的。(尽管这可以在IE9中运行) – PaulH 2012-01-06 22:36:35

+0

我认为浏览器(Chrome 16和ff10)在呈现文本之前缓存文本。我会使用javascript + ajax,一次获得一个ping输出并将其显示给用户。我会对强制页面渲染的可靠方法感兴趣... – al01 2012-01-06 22:57:32

+0

如果我愿意忍受页面顶部的异常对话框,我可以使其完美工作。我不认为浏览器无法做到这一点。 – PaulH 2012-01-06 22:59:10

3

我有一个可行的解决方案,但它是非高性能和恶心。我抛出异常,但隐藏异常对话框。

<?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> 

编辑

@克里斯的回答显示了一个更好的解决方案。

echo '<div style="display:none">'; 
for ($a = 0; $a < 768; $a++) 
    echo ' '; 
echo '</div>'; 
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>";      
}