【问题标题】:check if download is completed检查下载是否完成
【发布时间】:2010-12-06 11:57:42
【问题描述】:

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

我尝试了 PHP 手册中的一些代码,但它对我没有多大作用:

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
}

【问题讨论】:

标签: php download


【解决方案1】:

如果您混合使用 php(用于服务器端调用)和 javascript(用于客户端完整调用),则有一个解决方案。

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

我很确定你可以得到这样的好结果。 我希望这对其他人有帮助, 迈克

【讨论】:

    【解决方案2】:

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

      $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;
    

    【讨论】:

    • 这不起作用。 readfile 无法判断用户是否已取消。它返回没有错误,假设文件足够小,可以一次放入输出缓冲区,然后代码继续进行数据库更新。没有任何东西从 TCP 层向上传播以指示传递到管道的另一端。
    【解决方案3】:

    正如 Marc W 已经指出的那样,php 只能告诉您从服务器发送的内容,而不是客户端收到的内容,因此严格使用 php 是行不通的。

    但总是有可能要求用户通过按下一个按钮来确认下载,该按钮调用 JS 检查,通过生成 MD5 哈希并将其与服务器上文件的 MD5 哈希(服务器上的 MD5由您生成),并在成功比较时使用该 JS 脚本来更新您的数据库或使用它来调用 php-script 来执行相同的操作。

    您总是可以要求他们检查下载是否符合他们的预期,如果他们点击“是的,没关系”,然后更新数据库。


    已编辑: 回应 OP 的评论。
    谢谢,但不能依赖用户的配合。因为他们还必须为下载付费,所以最好我有所有的控制权。我想我会在访问脚本时更新数据库。那似乎是最可靠的。

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

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

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

    【讨论】:

    • 谢谢,但不能依赖用户的配合。因为他们还必须为下载付费,所以最好我有所有的控制权。我想我会在访问脚本时更新数据库。那似乎是最可靠的。
    • 感谢您的额外输入,但您忽略了您提到有 ajax 方式的事实。你有这方面的例子吗?
    • 不幸的是,我没有。我不太了解 JS/jQuery/Ajax,无法提供解决方案。可能值得您编辑您的原始问题以包含 Ajax、JS 和/或 jQuery 解决方案的请求和重新标记。很抱歉,我在这方面对你没有更多用处。
    【解决方案4】:

    这并不能真正告诉您用户的下载是否已完成。它会告诉您何时完成向用户发送字节,但它没有说明用户实际收到了多少字节。

    实际上,PHP(它是一种服务器端语言,而不是客户端语言)无法真正检测文件下载何时完成。您可以做的最好的事情是在下载开始时将其记录在数据库中。如果您绝对、完全、完全需要知道下载何时完成,您将不得不做一些事情,例如嵌入 Java 小程序或使用 Flash。但是,就用户的可用性而言,这通常不是正确的答案(为什么要求他们安装 Java 或 Flash 只是为了从您那里下载一些东西?)。

    【讨论】:

    • 是的,我已经实现了这一点,如果出现任何问题,我会回信联系我。我还使用了一个 jquery 插件在完成时获取回调,并且我没有页面刷新。
    • @hakre for connection_aborted from the doc:仅将 PHP 作为命令行脚本 (tty) 运行时。
    【解决方案5】:

    我认为通过 php 无法知道已经发送了多少位(实际上是通过客户端下载了),因为无法知道用户是否取消了下载或收到了整个文件。

    【讨论】:

    • 中间有网络服务器。 PHP 无法控制它。
    • 即使用户取消了,用户端的代理也可以完成下载
    • 谢谢,Gnibbler。那么这就说明了一切。这不是一个可靠的方法。
    猜你喜欢
    • 1970-01-01
    • 2011-06-21
    • 2019-09-24
    • 1970-01-01
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    相关资源
    最近更新 更多