我已经花了两天多时间解决这个问题。它看起来PHP函数connection_aborted()不能可靠地工作。有时它会报告与客户端的中断连接,但是大约50%它没有报告中止。
还有其他方法可以从PHP脚本中检测与客户端的中止连接吗?也许建立套接字连接或其他什么?
这是我最新版本的文件下载代码。下载甚至可以在大文件上正常工作,但connection_aborted()
只能偶尔使用。
// 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.")));
}
谢谢你,亲切的问候。
答案 0 :(得分:0)
使用默认设置,如果浏览器关闭连接,PHP将中止正在运行的脚本。您可以使用函数ignore_user_abort()
或ini设置ignore_user_abort
更改此默认行为。
为了使用函数connection_aborted()
,您需要先执行其中一个步骤,否则将永远不会达到connection_aborted()
。以下是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()
而被告知终止,也会调用此函数。以下示例显示了这一点:
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的连接处理。