dongniaoli1822 2014-02-16 20:09
浏览 82

替代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.

  • 写回答

1条回答 默认 最新

  • drnysdnnb2909701 2014-02-16 20:17
    关注

    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.

    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器