如何将数据刷新到浏览器但继续执行

aWe*_*per 20 php output-buffering

我有一个ob_start()和一个相应的ob_flush().我想刷新一部分数据并继续执行其余的数据.使用ob_flush()没有帮助.如果可能的话,休息需要在不显示浏览器加载的情况下发生

编辑:

我不想使用ajax

Zom*_*aya 16

我过去做过这个,这就是我解决它的方法:

ob_start();

/*
 * Generate your output here
 */ 

// Ignore connection-closing by the client/user
ignore_user_abort(true);

// Set your timelimit to a length long enough for your script to run, 
// but not so long it will bog down your server in case multiple versions run 
// or this script get's in an endless loop.
if ( 
     !ini_get('safe_mode') 
     && strpos(ini_get('disable_functions'), 'set_time_limit') === FALSE 
){
    set_time_limit(60);
}

// Get your output and send it to the client
$content = ob_get_contents();         // Get the content of the output buffer
ob_end_clean();                      // Close current output buffer
$len = strlen($content);             // Get the length
header('Connection: close');         // Tell the client to close connection
header("Content-Length: $len");     // Close connection after $len characters
echo $content;                       // Output content
flush();                             // Force php-output-cache to flush to browser.
                                     // See caveats below.

// Optional: kill all other output buffering
while (ob_get_level() > 0) {
    ob_end_clean();
}
Run Code Online (Sandbox Code Playgroud)

正如我之前在几条评论中所说,你应该注意抓取你的内容,因为这会改变你的内容的长度,但不会改变它的标题.它还可以缓冲您的输出,因此它不会立即发送到客户端.
你可以尝试让apache知道不要使用gzip你的内容apache_setenv('no-gzip', '1');.但是,如果您使用重写规则转到您的页面,这将无法工作,从那时起它也将修改这些环境变量.至少,它对我这样做了.

请参阅手册中有关将内容刷新给用户的更多警告.


Cor*_*bin 15

ob_flush写缓冲区.换句话说,ob_flush告诉PHP给Apache(或nginx/lighttpd/whatever)输出,然后让PHP忘记它.一旦Apache拥有输出,它就可以随心所欲地完成任务.(换句话说,在ob_flush它无法控制之后是否立即写入浏览器).

所以,简短回答:没有保证的方法可以做到这一点.

只是一个猜测,你可能正在寻找AJAX.每当人们在你正在进行页面内容加载时试图操纵时,AJAX几乎总是正确的路径.

如果您想在后台继续执行任务,则可以使用ignore_user_abort(此处详细说明),这通常不是最佳方法.你基本上失去了对该线程的控制权,在我看来,Web服务器线程不是重处理所属的地方.

我会尝试从面向网络的东西中提取它.这可能意味着一个cron条目或者只是从PHP内部生成后台进程(虽然从脚本执行内部开始的进程不会因脚本而死,并且脚本不会等到它在死亡之前完成).

如果你这样做了,那就意味着你甚至可以在必要时制作某种状态系统.然后,您可以监视执行情况并为用户定期更新进度.(从技术上讲,你也可以使用ignore_user_abort-ed脚本创建一个状态系统,但它对我来说似乎并不干净.)


Afr*_*din 5

这是我的功能

function bg_process($fn, $arr) {
    $call = function($fn, $arr){
        header('Connection: close');
        header('Content-length: '.ob_get_length());
        ob_flush();
        flush();
        call_user_func_array($fn, $arr);
        };
    register_shutdown_function($call, $fn, $arr);
    }
Run Code Online (Sandbox Code Playgroud)

最后将要执行的函数包裹起来,在php关闭连接后。当然浏览器会停止缓冲。

function test() {
    while (true) {
        echo 'this text will never seen by user';
        }
    }
Run Code Online (Sandbox Code Playgroud)

这是调用函数的方法

bg_process('test'); 
Run Code Online (Sandbox Code Playgroud)

第一个参数是 callable,第二个参数是要传递给带有索引数组的“test”函数的数组

注意:我不在ob_start()脚本的开头使用。