fat-free framework flush partial output

2019-05-31 00:39发布

I'm writing some back-office web pages for maintenance of our systems. I'm using F3 I have one route with a long processing, divided in many subprocesses. I made one template per subprocess, this way:

$f3->route('GET /someroute', function($f3) {
   dosomework();
   echo template::instance()->render('template-job1.html');

   dosomeotherwork();
   echo template::instance()->render('template-job2.html');
}

I would like that i get in browser partial output as it is ready (one template at time) but what i get it is i have to wait for all the output.

If i try with a standard php output (e.g. with some sleep() and some echo()) I get line by line and not all together at the end of process.

Another example with f3:

$f3->route('GET /output', function($f3) {
    echo "pippo\n";

    for ($i=0;$i<100;$i++) {
        echo ".";
        sleep(1);
    }
});

Does output after 100s. Instead if I write a simple php page:

<?php
echo "pippo2\n";

    for ($i=0;$i<100;$i++) {
        echo ".";
        sleep(1);
    }

It outputs a dot every second.

1条回答
虎瘦雄心在
2楼-- · 2019-05-31 01:18

That's because the framework stores the complete response before sending it to the client, using PHP's output buffering control.

So you should first disable the output buffer and turn on implicit output flush:

$f3->route('GET /output', function($f3) {

    // disable output buffering
    while (ob_get_level())
        ob_end_flush();

    // turn implicit flush
    ob_implicit_flush(1);

    // now every output call should be flushed instantly to the client
    for ($i=0;$i<10;$i++) {
        echo $i;
        sleep(1);
    }

});

NB1: disabling output buffering will prevent the framework from populating the RESPONSE variable.

NB2: some browsers may themselves buffer the received output, i.e wait a minimum amount of data before displaying it. See flush for details.

查看更多
登录 后发表回答