使用php readfile确定成功下载

时间:2012-01-07 16:38:19

标签: php download readfile

我需要知道用户是否选择了下载然后单击了取消按钮,这与有错误的readfile不同。我已经检查了readfile函数返回的计数,但它显示了文件中的字节,即使用户从“另存为”对话框中取消了下载。

需要这样做的原因是因为我的网站有一次性下载,其中一个成员允许其他用户下载文件一次,然后权限消失。但是如果一个成员点击下载按钮然后决定不立即下载它,我不希望我的数据库得到更新以显示他们得到了该文件。

这涉及知识产权保护,因为文件是上传它们的成员的财产,我需要保留其他成员下载文件的审计跟踪,以防它们开始在互联网上浮动。但是如果readfile函数总是反映文件大小(意味着那些字节以某种方式传输),我无法知道该文件是否实际上已下载。

我已经看过很多关于这个主题的帖子,但是对于经常需要的东西没有真正的解决方案 - 他们是否下载了?只知道他们点击下载按钮并没有真正说明他们是否决定使用它,因为“另存为”对话框允许某人取消实际完成下载。

为了完整性,这是我的下载代码,直到readfile函数:

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header("Content-Disposition: attachment; filename=$download_name");
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize("sub/$doc_file"));
    ob_clean();
    flush();
    $wasdownloaded = readfile("sub/$doc_file");

3 个答案:

答案 0 :(得分:1)

首先需要ignore_user_abort()

这将允许您的脚本在用户点击取消或转义后继续。

然后,您必须print输出该文件,并持续检查connection_aborted()

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$download_name");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize("sub/$doc_file"));
ob_clean();
flush();

$fp=fopen("sub/$doc_file","rb");

while(!feof($fp))
{
    print(fread($fp,1024*8));

    flush();
    ob_flush();
    if( connection_aborted() )
    {
        //do code for handling aborts
    }
}

答案 1 :(得分:1)

我担心正确答案是“不可能” - 让我解释一下:你可能能够正确地弄清楚,当文件越过电线时,你无法可靠地弄清楚,客户是否扔掉了或者不

示例(按时间顺序排列):

  • MSIE上的用户点击下载,并显示“保存位置”对话框。
  • 此对话框打开时,下载将在后台启动。
  • 用户在对话框中导航或者什么都不做(电话响了,他说话)
  • 后台下载完成,您的脚本将下载视为完整
  • 用户点击“取消”
  • MSIE删除临时文件,下载永远不会以用户可访问的形式存储

结果:

  • 用户将文件视为“未下载” - 而且他是正确的
  • 您的应用将该文件视为“已正确下载” - 并且该文件正确

答案 2 :(得分:0)

在php.net上使用此评论:http://www.php.net/manual/en/function.fread.php#72716fclose,您可以确定文件是否已成功下载,因为您正在检查用户是否已中止与connection_status()

的连接