2009-10-13 113 views
7

我的问题是 - 什么是检测下载是否完成的最佳方法, 因为之后我想更新数据库。检查下载是否完成

我尝试了一些来自php manuel的代码,但它对我没有多大帮助。

Header ("Content-Type: application/octet-stream"); 
Header ("Content-Length: ".filesize($file)); 
Header("Content-Disposition: attachment; filename=$filename"); 

// buffered read not using readfile($file); 

if ($fp = fopen($bestand, 'rb')) { 
    while (!feof($fp)) { 
     $buf = fread($fp, 4096); 
     echo $buf; 
     $bytesSent += strlen($buf); /* We know how many bytes were sent to the user */ 
    }  
} 

if ($bytesSent == filesize($fp)) { 
    //do something with db 
} 

感谢进阶,理查德

+0

IM找到了一个很好的解决方案来实现纯PHP: http://bytes.com/topic/php/answers/551302-how-detect-if-file-download-completed-取消 – StefanoCudini

回答

9

这并不是真的会告诉你下载是否已经完成。它会告诉你什么时候已经完成了向用户发送字节,但是它没有说明用户实际接收了多少字节。

实际上,PHP(服务器端,而不是客户端语言)无法真正检测文件下载何时完成。您可以做的最好的事情是在数据库开始时记录下载数据。如果你绝对,完全和完全需要知道什么时候下载完成,你必须做一些事情,比如嵌入Java applet或者使用Flash。然而,通常这不是您用户可用性的正确答案(为什么要求他们安装Java或Flash来从您那里下载东西?)。

+0

是的,我已经实现了这一点,并给出了一个返回信息,如果出现任何问题,请与我联系。我也使用jquery插件来完成回调,我没有页面刷新。 – Richard

+0

http://php.net/function.ignore_user_abort - http://www.php.net/connection_aborted – hakre

+0

@hakre for connection_aborted from the doc:仅将PHP作为命令行脚本运行(tty)。 – Mike

1

我不认为这是可能通过PHP知道有多少咬伤已经(通过客户端和实际下载)发送出去,因为没有办法知道用户已取消下载或收到整个文件。

+0

中间有网络服务器。 PHP没有控制它。 – powtac

+1

也是在用户端的代理可能会完成下载,即使用户已经取消了它 –

+0

谢谢,Gnibbler。然后说这一切。这不是一个可靠的方法。 – Richard

2

正如Marc W已经指出的那样,php只能告诉你你从服务器发送了什么,而不是客户端收到了什么,所以严格使用php是一个非启动器。

但是总是有可能通过按下一个按钮调用JS检查来确认下载,方法是生成一个MD5散列并将其与服务器上的文件的MD5散列进行比较(服务器上MD5是由你生成的),并成功的比较使用JS脚本来更新你的数据库或使用它来调用一个PHP脚本来做同样的事情。

你总是可以让他们检查下载是他们的预期,如果他们点击“是的,没关系”,那么更新数据库。


编辑:回应OP的评论。

谢谢,但你不能依赖于用户的合作。因为他们还必须为下载付费,所以我最好拥有所有的控制权。我想我会在脚本被访问时更新数据库。那似乎是最可靠的。

如何使用Ajax控件来启动和维护下载,并在完成验证其完整性和运行更新到您的数据库?

我建议不要自动假设你的客户会撕掉你,尽管,无论你最终选择了什么。很好地问他们'它对你有用吗?'如果没有,导致错误报告可能对你和他们有用。

但是,无论如何,虽然有些用户可能会为额外副本说'不',但您必须平衡其成本与增加的工作负载的成本以防止其发生。如果维持“诚实”的成本超过了他们获取额外副本的潜在/可能成本,那就没什么意义了。

+0

谢谢,但你不能依赖于用户的合作。 因为他们还必须为下载付费,所以最好是我拥有所有的控制权。我想我会在脚本被访问时更新数据库。那似乎是最可靠的。 – Richard

+0

感谢您的额外输入,但是您忽略了您提到有ajax方式的事实。你有这样的例子吗? – Richard

+0

不幸的是,我没有。我不太了解JS/jQuery/Ajax以提供解决方案。您可能需要编辑您的原始问题,以包含针对Ajax,JS和/或jQuery解决方案的请求和重新标记。对不起,我不能在这方面对你更有用。 –

-4

以下代码有效。如果客户端停止下载,数据库不会更新,链接可能会再次触发。

$file='pathto.zip'; 

    header("Content-type: application/zip"); 
    header("Content-Disposition: attachment; filename=$file"); 
    header("Pragma: no-cache"); 
    header("Expires: 0"); 
    readfile("$file"); 

    $sql = "UPDATE YOUR TABLE"; 

    exit; 
+0

这不起作用。 'readfile'不能分辨用户是否已经取消。它返回时没有错误,假设文件足够小以适应输出缓冲区,然后代码继续进行数据库更新。没有任何东西从TCP层向上传播,以指示传递到管道的另一侧。 –

+0

这不起作用。 – Mike

+0

这不起作用了。 –

0

有一个解决方案,如果你是混合php(用于服务器端调用)的JavaScript(用于客户端完成调用)。

看看这个答案对我如何Detect when browser receives file download

敢肯定,你可以有一个很好的结果是这样的。 我希望这帮助了别人, 迈克