我有一个相当长的数据挖掘脚本,在其中的一部分我将一些信息回显到页面(实际上是在 foreach 循环期间。)
但是我注意到信息不是像我希望的那样立即发送到浏览器,而是以“段”的形式发送到浏览器。
在我的回声之后我可以使用一些功能来立即将所有数据发送到浏览器吗?
谢谢。
你可能想要flush()
. 但是,PHP 可能正在使用输出缓冲。有几种方法可以改变事情,但简而言之,你可以flush()
,然后ob_flush()
。
您可以尝试在每次回显后使用 flush(),但即使这样也不能保证根据您正在运行的 Web 服务器写入客户端。
是的,将输出填充到 1024 字节将导致大多数浏览器开始显示内容。
但我们也从@nobody 对问题“如何在每次 `echo` 调用后刷新输出? ”的回答中了解到,1024 字节浏览器缓冲效果仅在浏览器必须猜测页面的字符编码时发生,可以通过发送正确的 Content-Type 标头(例如“Content-Type: text/html; charset=utf-8”),或通过适当的 html 元标记指定内容字符集。它在所有浏览器中都对我有用。
所以基本上,所有需要做的就是:
header('Content-Type: text/html; charset=utf-8');
ob_implicit_flush(true);
不需要额外的填充或冲洗,这对代码有很大的美观效果!当然,标题必须在任何内容之前发送,并且还必须确保没有输出缓冲正在进行。
问题绝对为我解决了!如果它对您有用,请 (+1) @nobody 回答另一个问题。如果仍然遇到问题,我建议查看其他问题的答案,以了解可能会阻止隐式刷新正常工作的其他特定情况。
另请注意,某些浏览器在响应正文包含一定数量的数据(如 256 或 1024 字节)之前不会开始显示任何内容。我在页面顶部附近看到了填充数据之前的应用程序,在它们进行刷新之前,它们有一个 1024 字符长的注释。这有点骇人听闻,但很有必要。
这适用于 Internet Explorer 和 Safari IIRC。
所以,
我喜欢只使用
while (ob_get_level()) ob_end_flush();
在我的脚本开头附近的某个地方,然后只是
flush();
每当我想冲洗。这假定您根本不想要任何输出缓冲,即使它是在您的脚本之前设置的(例如在 PHP.ini 或 htaccess 配置中)。
您应该能够使用这样的东西来强制立即发送输出。将其放在您希望发送输出的代码部分。
flush();
ob_flush();
呸!我终于找到了谷歌浏览器缓冲区问题的答案!感谢boymakesh 朝着正确的方向前进。这是我使用的功能:
function buffer_flush(){
echo str_pad('', 512);
echo '<!-- -->';
if(ob_get_length()){
@ob_flush();
@flush();
@ob_end_flush();
}
@ob_start();
}
这就是我所说的:
show_view('global', 'header'); // Echos the <html><head>... tags and
// includes JS and CSS.
show_view('global', 'splash_screen'); // Shows a loading image telling
// the user that everything's okay.
buffer_flush(); // Pretty obvious. At this point the loading view shows
// up on every browser i've tested (chrome, firefox,
// IE 7 & 8)
show_view('global', 'main'); // Has a loop that echos "Test $i<br>" 5
// times and calls buffer_flush() each time.
show_view('global', 'footer'); // End the html page and use JQuery to
// fade out the loading view.
要在 Google chrome 中完美解决此问题,请尝试以下操作:
$i = 0;
$padstr = str_pad("",512," ");
echo $padstr;
while ($i <= 4){
$padstr = str_pad("",512," ");
echo $padstr;
echo "boysmakesh <BR> ";
flush();
sleep(2);
$i = $i + 1;
}
Ee 在发送每个回声之前发送 512 个字节。在刷新之前不要忘记放在<BR>
内容的末尾。否则它在 Chrome 中不起作用,但在 IE 中起作用。
我们填充的数据取决于浏览器。对于某些浏览器来说,256 字节就足够了,但有些浏览器需要 1024 字节。对于铬,它是 512。
ignore_user_abort(TRUE); // run script in background
set_time_limit(0); // run script forever
$interval=150000;
$i = 0;
if(
strpos($_SERVER["HTTP_USER_AGENT"], "Gecko") or
strpos($_SERVER["HTTP_USER_AGENT"], "WebKit")
){
# important to change browser into quirks mode
echo '<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
}
function buffer_flush(){
echo "\n\n<!-- Deal with browser-related buffering by sending some incompressible strings -->\n\n";
for ( $i = 0; $i < 5; $i++ )
echo "<!-- abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono -->\n\n";
while ( ob_get_level() )
ob_end_flush();
if(ob_get_length()){
@ob_flush();
@flush();
@ob_end_flush();
}
@ob_start();
}
ob_start();
do{
if($i<10){
buffer_flush();
echo ". ";
buffer_flush();
usleep($interval);
} else {
echo sprintf("<pre>%s</pre>", print_r($_SERVER,true));
break;
}
$i++;
}while(true);
在 IIS 7、IE 11(win 服务器)上运行 php 5.5 我发现这可以作为文件的开头行。请注意,将 while 语句放在标头之前会导致标头已写入错误。
header('Content-Type: text/html; charset=utf-8');
while (ob_get_level()) ob_end_flush();
ob_implicit_flush(true);
脚本中对 ob_flush() 的进一步引用导致缓冲区不存在错误。
当我处理文件并将 sql 语句发送到浏览器时,这工作正常,但是当我连接数据库(ms 服务器 2008)时,直到脚本完成,我才返回任何输入。
根据 thomasrutter 的回答,这种组合终于对我有用
while (ob_get_level()) ob_end_flush();
ob_implicit_flush(true);