使用php readfile确定成功下载

使用php readfile确定成功下载,php,download,readfile,Php,Download,Readfile,我需要知道用户是否选择了下载,然后单击了取消按钮,这与readfile出现错误不同。我已经检查了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");
你首先需要

这将允许您的脚本在用户点击“取消”或“退出”后继续运行

然后,您必须
打印出该文件,并不断检查


在php.net上使用以下注释:
fclose
上,您将能够确定文件是否已成功下载,因为您正在检查用户是否中止了与的连接。我担心正确的答案是“不可能的”-让我解释一下:您可能能够正确地计算出文件何时越过了连接线,但您无法可靠地计算出,不管客户是否把它扔掉

示例(按时间顺序):

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

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

您所说的可能的重复就是根本不使用readfile,这就是这里的结果,对吗?但是fopen和fread策略是否仍会为用户提供相同的保存/取消对话框,以便将文件保存到磁盘?是的,只要设置了正确的标题,浏览器将下载而不是显示。文件的输出方式并不决定文件是由标题控制的“下载”还是“显示”。此外,如果使用这种方式,请确保在conneciton_中止检查中有一个exit、die或break调用,否则它将继续将文件发送到服务器输出缓冲区。我想知道,只有当文件仍在下载到临时文件时,连接中止是否有效。上面的代码不会改变动态,如果单击“另存为”框中的“取消”按钮,仍然显示为已完成。我用来测试的文件是50K的,所以它下载到下载文件夹中的临时文件的速度比我点击取消按钮的速度要快得多,而且依赖于它不是一个解决方案,reallyNice。我不知道这个函数的连接。那将对我有很大帮助。我将了解我的访问者是否有足够的耐心下载一些大文件,即使我的Web服务器提供的下载率很低。好吧,这不是好消息。见鬼,在“另存为”框中有一个按钮显示“取消”,但如果没有将tempfile重命名为已保存的文件,那又有什么好处呢?在我看来,任何需要一次性下载的人都必须能够知道它是否真的有效,这样他们才能将其标记为完成并删除下载特权
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
    }
}