0

Greeting guys,

I'm working on my php framework. It has a response manager to wrapper php's header, cookie, and buffer functions. I use this to send result page to user.

However, even the page header and contents already be sent by using ob_start -> ob_end_flush -> flush, the browser still hanging and wait for script to complete.

It cause problems when i want to do some slow job like update current user's session or just send a mail or upload something. User will have to wait until everything done, even they already have the whole page including header.

What I want to know is, how to make browser know the page is completely loaded, so it can display the page right now?

Thank you!

//////////////////////////// Abandoned Solutions ////////////////////////////

Abandoned Solution 1

In the past, i usually use the combination of ob_start -> ob_end_flush -> ob_flush -> flush to fix this problem, it seems will like this:

function send($content) {
    ob_start();

    echo $content;

    ob_end_flush();
    ob_flush();
    flush();

    return true;
}

But the ob_flush will throw a E_NOTICE says it have "No buffer to flush". I don't want to fix this by just mute this E_NOTICE (and in fact, in my framework, there is no way to mute any error). So this is not the way to solve this problem.

Abandoned Solution 2

I also try to close connection after content sent, code will like this:

function send($content) {
    ob_start();

    header('Connection: close');

    echo $content;

    ob_end_flush();

    flush();

    return true;
}

It can solve the problem with out any error, but it bring another problem: Seems client's connection will be close after page received, and when they want to open another page, they have to reconnect. This will generate extra load on network.

Abandoned Solution 3

Yeah, some people suggested me to use fastcgi, and use fastcgi_finish_request(); But i want to make my code more compatible between environments, so it actually not a option.

  • Why would the browser hang? Once the PHP is done output is sent and connection is closed. Try a `die;` after the flush and see if anything changes. Does your PHP script terminate properly? – CodeAngry Jul 16 '13 at 01:54
  • @CodeAngry: Sorry, but i don't want to use die, it will make my question pointless. I want to make script continue run after page sent. –  Jul 16 '13 at 02:05

1 Answers1

0

On IIS you cannot break the connection before the fastcgi finishes. You need to use fascgi_finish_request()^ to manually force the finish of the current CGI.

On Apache you can use the Content-Length: 0 redirect trick^ which works great but does not work on IIS (at least not in my experience).

PS: And make sure you do the ignore_user_abort(true) and extend the runtime limit set_time_limit(0)(infinte) before any of these to prevent PHP from closing when connection is closed by client.

PPS: Tasks run after page is sent should go into cronjobs. It's the cleaner way to do things.

Community
  • 1
  • 1
CodeAngry
  • 12,760
  • 3
  • 50
  • 57