我在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诊断错误和调用堆栈,上面写着:
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;
,我会得到类似的错误,并且在所有浏览器中输出都是实时的。是不是因为打印异常的方式导致了这种情况的发生?
某些web浏览器在某些条件下,在开始渲染页面之前缓冲前x个字节。
尝试先输出大量空白
我有一个有效的解决方案,但它是非性能的,而且很恶心。我抛出了一个异常,但隐藏了异常对话框。
<?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>';
只需添加此项即可刷新缓冲区:
if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) {
echo "<div style='"display:none'">";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo " ";
echo "</div>";
}
它必须在循环内部。或者在需要实时显示的两个输出之间。
这里有一个简写技巧:
添加以下内容:
if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) {
echo "<div style='"display:none'"></div>";
}
ob_end_flush()刷新php输出缓冲区,并需要使用ob_start()创建活动输出缓冲区。
我认为您只想调用flush()将数据发送到客户端。
<?php
ob_implicit_flush(true);
flush();
system('ping -n 10 www.google.com');
?>
在代码中,错误很容易解释。
您在第3行调用ob_end_flush()
,但是(就像错误所说的),没有要刷新的输出。本质上,第3行是无用的,因为没有发送任何输出,所以删除该行将修复错误。如果将其合并到一个较大的文件中,则可能需要保留ob_end_flush()
,因为可能已经捕获了一些输出。
编辑:既然你需要冲洗它,要么:
a: 将ob_start();
添加到文件顶部。
b: 用flush();
代替ob_end_flush();
第二版:由于第一个似乎不起作用,这是我能提供的最好的:如何实时(在脚本完成之前)回声输出?