PHP 错误:ob_flush() [ref.outcontrol]:未能刷新缓冲区.没有缓冲区可以刷新

2021-12-26 00:00:00 while-loop flush php ajax

有人可以保存这两个文件并运行它们并告诉我为什么我收到错误ob_flush() [ref.outcontrol]: failed to refresh buffer. No buffer to refresh".我试着用谷歌搜索,它说我必须使用 ob_start();但是当我这样做时,它不会逐行打印出来,而是在完成后从 FOR 循环中返回整个对象.我对 PHP 有点陌生,所以我不知道还有什么地方可以看..

test_process.php

//这个脚本会将 1 到 100 的数字写入文件//并不断向用户发送信息$fp = fopen('/tmp/output.txt', 'w') or die('打开失败');设置时间限制(120);忽略用户中止(真);for( $i = 0; $i <100; $i++){echo "<script type="text/javascript">parent.document.getElementById('foo').innerHTML += 'Line $i<br/>';</script>";回声 str_repeat('', 2048);冲洗();ob_flush();睡眠(1);fwrite( $fp, "$i
");}fclose($fp);

ma​​in.html

<头><script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" charset="utf-8"></script><style type="text/css" media="screen">.msg{ 背景:#aaa;填充:.2em;边框底部:1px #000 实心}.new{ 背景色:#3B9957;}.error{ 背景色:#992E36;}</风格><身体><iframe id="loadarea" width="1024px" height="768px"></iframe><br/><脚本>功能助手(){document.getElementById('loadarea').src = 'test_process.php';}函数杀死(){document.getElementById('loadarea').src = '';}<input type="button" onclick="helper()" value="Start"><input type="button" onclick="kill()" value="停止"><div id="foo"></div>

解决方案

我认为您将 ob_flush()flush() 混淆了.ob_start()ob_flush() 处理捕获所有输出的 PHP 内部输出缓冲区,flush() 是刷新 code>STDOUT 就像在其他编程语言中一样.

示例:

您的输出不会打印,因为您的网络服务器可能会缓冲内容.尝试关闭压缩和输出缓冲:

@apache_setenv('no-gzip', 1);@ini_set('zlib.output_compression', 0);@ini_set('implicit_flush', 1);

还请记住,Safari 和 Internet Explorer 有一个内部 1K 缓冲区.因此,您需要添加 1 KB 的填充数据(如空格),以使它们呈现.

编辑 2:你的实现被破坏了.您想使用 ajax 轮询您的数据.在客户端使用 jQuery:

0%

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><script type="text/javascript">函数 doPoll(){$.post('script-that-returns-stuff.php', function(data) {$("#counter").html(数据);设置超时(doPoll,5000);});}doPoll();

然后在 script-that-returns-stuff.php 中:

Could someone please save these 2 files and run them and tell me why I get the error " ob_flush() [ref.outcontrol]: failed to flush buffer. No buffer to flush". I tried googling around and it says that I have to use ob_start(); but when I do then it doesn't print out line by line, but rather returns the whole object from the FOR loop when it has completed. I'm kinda new to PHP so I'm not sure where else to look..

test_process.php

// This script will write numbers from 1 to 100 into file
// And sends continuously info to user
$fp = fopen( '/tmp/output.txt', 'w') or die('Failed to open');
set_time_limit( 120);
ignore_user_abort(true);

for( $i = 0; $i < 100; $i++){
    echo "<script type="text/javascript">parent.document.getElementById( 'foo').innerHTML += 'Line $i<br />';</script>";
    echo str_repeat( ' ', 2048);
    flush();
    ob_flush();
    sleep(1);
    fwrite( $fp, "$i
");
}

fclose( $fp);

main.html

<html>
    <head>
        <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" charset="utf-8"></script>

        <style type="text/css" media="screen">
            .msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
            .new{ background-color:#3B9957;}
            .error{ background-color:#992E36;}
        </style>

    </head>
    <body>

        <iframe id="loadarea" width="1024px" height="768px"></iframe><br />
        <script>
            function helper() {
                document.getElementById('loadarea').src = 'test_process.php';
            }
            function kill() {
                document.getElementById('loadarea').src = '';
            }
        </script>

        <input type="button" onclick="helper()" value="Start">
        <input type="button" onclick="kill()" value="Stop">
        <div id="foo"></div>


</body>
</html>

解决方案

I think you are confusing ob_flush() with flush(). While ob_start() and ob_flush() handles a PHP internal output buffer that catches all outputs, flush() is the normal function that flushes STDOUT like in other programming languages.

Example:

<?php
ob_start();
echo "Foobar
Foobar
Foobar
";
// Nothing printed yet
ob_flush(); // Now it is printed.

echo "Foobar
"; // Printed directly, because contains a line ending.

echo "Foobar"; // Not printed, because normally buffers are flushed on line endings
flush();  // Printed.

EDIT:

Your output is not printed, because your webserver may buffer the contents. Try to turn off compression and output buffering:

@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 0);
@ini_set('implicit_flush', 1);

Please also keep in mind, that Safari and Internet Explorer have an internal 1K buffer. So you need to add 1 KB of padding data (like spaces), to make them render.

EDIT 2: Your implementation is broken. You want to poll your data with ajax. Use jQuery on the client side:

<div id="counter">0%</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
<script type="text/javascript">
function doPoll(){
    $.post('script-that-returns-stuff.php', function(data) {
        $("#counter").html(data);
        setTimeout(doPoll,5000);
    });
}
doPoll();
</script>

Then in script-that-returns-stuff.php:

<?php
$file = explode("
", file_get_contents("/tmp/output.txt"));
$last_line = $file[count($file)-1];
echo $last_line."%";

相关文章