简体   繁体   中英

PHP script doesn't exit on browser exit

Why this dummy script keeps running event if the client closes the browser (so the connection to the server)?

while ( true )
{
    sleep( 1 );
    file_put_contents( '/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND );
}

It's unexpected to me according to this . Also this example doesn't seem to work.

And set_time_limit with a non-zero parameter simply does nothing.

I'd like some clarifications.

If you try to write some output to the browser in that loop, you should find the script aborts if the connection has been terminated. This behaviour is hinted at in the documentation for ignore_user_abort

When running PHP as a command line script, and the script's tty goes away without the script being terminated then the script will die the next time it tries to write anything, unless value is set to TRUE

I tried a few experiments myself, and found that even if you do attempt some browser output, the script will keep running if the output buffer isn't full yet. If you turn output buffering off, the script will abort when output is attempted. This makes sense - the SAPI layer should notice the request has been terminated when it tries to transmit the output.

Here's an example...

//ensure we're  not ignoring aborts..
ignore_user_abort(false);

//find out how big the output buffer is
$buffersize=max(1, ini_get('output_buffering'));


while (true)
{
    sleep( 1 );

    //ensure we fill the output buffer - if the user has aborted, then the script
    //will get aborted here
    echo str_repeat('*', $buffersize)."\n";

    file_put_contents( '/tmp/foo' , "I'm alive ".getmypid()."\n" , FILE_APPEND );
}

That demonstrates what triggers the abort. If you had a script which was prone to enter an endless loop with no output, you could use connection_aborted() to test whether the connection is still open.

set_time_limit only restricts the time spent in php code. Most of the time(I'd guess >99.9%) in your program is spent in system calls, writing data to a file and sleeping.

ignore_user_abort only aborts when you're writing something to the client (not in a local file) - there's simply no way you can distinguish an unused and a terminated connection otherwise in TCP, unless the client excplicitely terminates the connection with an RST packet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM