替代PHP函数connection_aborted()?

I spent already over two days on this problem. It looks that PHP function connection_aborted() does not work reliably. Sometimes it reports aborted connection with the client properly, but in about 50% it does not report the abort.

Is there any other way to detect aborted connection with the client from within the PHP script, please? Maybe establishing socket connection or anything else?

Sample code:

This is my latest version of the file downloading code. Downloading works properly even on large files, but connection_aborted() works only occasionally.

// disable script abort
ignore_user_abort(true);

// never expire this download script
set_time_limit(0);

 while(!feof($fileObject) && (connection_status()==0))
        {
            //usleep(100000);

            print(@fread($fileObject, $chunkSize));

            // gradually output buffer to avoid memory problems by downloading large files
            ob_flush();
            flush();

            $nLoopCounter++;
            $transferred += $chunkSize;
            $downloadPercentage = (($nLoopCounter * $chunkSize) / $fileSize) * 100;

            $result = mysqli_query($dbc, "UPDATE current_downloads SET progress_percent=$downloadPercentage, transferred=$transferred, connection_aborted=$strConnectionAborted, iteration=$nLoopCounter WHERE user_id=1;");
            if($result == false)
            {
                // close the database connection
                mysqli_close($dbc);

                // close the file
                fclose($handle);

                // prepare output message
                exit(json_encode(array("result" => false, "error" => "Error Processing Database Query.")));
            }
        }

        // check if the client was disconnected
        // important for cancelled or interrupted downloads
        if ( (connection_status()!=0) || (connection_aborted()!=0) )
        {
            // empty the output buffer
            ob_flush();
            flush();

            ChromePhp::log("Connection Aborted");

            // sent to the database that the connection has been aborted
            $result = mysqli_query($dbc, "UPDATE current_downloads SET connection_aborted=TRUE WHERE user_id=1;");

            // close the database connection
            mysqli_close($dbc);

            // close the open file
            @fclose($fileObject);

            exit(json_encode(array("result" => false, "error" => "Connection with the client was aborted.")));
        }

Thank you and kind regards.

With default settings PHP will just abort the running script if the browser closes the connection. You can change this default behaviour using the function ignore_user_abort() or the ini setting ignore_user_abort.

In order to use the function connection_aborted() you need to do one of those steps before because otherwise connection_aborted() will never reached. Here comes an example with ignore_user_abort():

ignore_user_abort(TRUE);
for($i = 0; $i < 10; $i++) {
    sleep(1);
    // click the stop button in your browser ...
    if(connection_aborted()) {
        // we can't use echo anymore as the connection to the
        // browser was closed. that's why we write to test file
        file_put_contents('/tmp/test.file', 'The connection was aborted');
    }
}

But that's not all. If you register a shutdown function using register_shutdown_function() this function will get called even if the scripts has been told to terminate because of missing ignore_user_abort(). The following example shows this:

register_shutdown_function(function() {
    // click the stop button in your browser ...
    if(connection_aborted()) {
        // we can't use echo anymore as the connection to the
        // browser was closed. that's why we write to test file
        file_put_contents('/tmp/test.file', 'The connection was aborted');
    }
});

You can follow this article in the documentation: http://www.php.net/manual/en/features.connection-handling.php. It explains PHP's connection handling.