PHP 函数 connection_aborted() 的替代方案? [英] Alternative to PHP Function connection_aborted()?

查看:23
本文介绍了PHP 函数 connection_aborted() 的替代方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个问题上已经花了两天多的时间.看起来 PHP 函数 connection_aborted() 不能可靠地工作.有时它会正确报告与客户端的连接中止,但在大约 50% 的情况下它不会报告中止.

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.

有没有其他方法可以从 PHP 脚本中检测与客户端的连接中止?也许建立套接字连接或其他任何东西?

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?

这是我最新版本的文件下载代码.即使在大文件上下载也能正常工作,但 connection_aborted() 只能偶尔工作.

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.

推荐答案

在默认设置下,如果浏览器关闭连接,PHP 只会中止正在运行的脚本.您可以使用函数 ignore_user_abort() 或 ini 设置 ignore_user_abort 更改此默认行为.

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.

为了使用函数 connection_aborted(),您需要先执行这些步骤之一,否则 connection_aborted() 将永远不会到达.下面是一个 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');
    }
}

但这还不是全部.如果您使用 register_shutdown_function() 注册关闭函数,即使脚本因缺少 ignore_user_abort() 而被告知终止,该函数也会被调用.以下示例显示了这一点:

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');
    }
});

您可以在文档中关注这篇文章:http://www.php.net/manual/en/features.connection-handling.php.它解释了 PHP 的连接处理.

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

这篇关于PHP 函数 connection_aborted() 的替代方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆