Search code examples
phptermination

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.


Solution

  • 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.