php 检查下载是否完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1563187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
check if download is completed
提问by Richard
What is the best possible way to detect if a download is completed, because afterward I want to update the database.
检测下载是否完成的最佳方法是什么,因为之后我想更新数据库。
I tried some of this code from the PHP manual, but it doesn't do much for me:
我尝试了 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
}
回答by Marc W
That's not really going to tell you if the download has completed for the user. It will tell you when youhave finished sending bytes to the user, but it says nothing about how many of them the user has actually received.
这并不能真正告诉您下载是否已为用户完成。它会告诉你,当你完成发送字节给用户,但它没有提到的用户有多少人实际已收到。
In reality, there is no way with PHP (which is a server-side, not a client-side, language) to truly detect when a file download has completed. The best you can do is log the download in your database when it begins. If you absolutely, completely and totally need to know when the download has completed, you'll have to do something like embed a Java applet or use Flash. However, usually that is not the correct answer in terms of usability for your user (why require them to have Java or Flash installed just to download something from you?).
实际上,PHP(它是一种服务器端语言,而不是客户端语言)无法真正检测文件下载何时完成。您能做的最好的事情是在下载开始时将下载记录到您的数据库中。如果您绝对、完全和完全需要知道下载何时完成,则必须执行诸如嵌入 Java 小程序或使用 Flash 之类的操作。然而,就您的用户的可用性而言,这通常不是正确的答案(为什么要求他们安装 Java 或 Flash 只是为了从您那里下载一些东西?)。
回答by David says reinstate Monica
As Marc W's already pointed out php can only tell you what you've sent from the server, not what the client's received, so using strictly php is a non-starter.
正如 Marc W 已经指出的那样,php 只能告诉你你从服务器发送了什么,而不是客户端收到了什么,所以严格使用 php 是不可能的。
But there is always the possibility of asking the user to confirm the download by pressing a button that calls a JS check by generating an MD5 hash and comparing that to the MD5 hash of the file on your server (the on-server MD5 being generated by you), and on a successful comparison use that JS script to update your db or use it to call a php-script to do the same.
但是总是有可能通过按下一个按钮来要求用户确认下载,该按钮通过生成 MD5 哈希并将其与服务器上文件的 MD5 哈希进行比较来调用 JS 检查(服务器上的 MD5 是由您),并在成功比较时使用该 JS 脚本来更新您的数据库或使用它来调用 php 脚本来执行相同的操作。
You could always just ask them to check the download is what they expected and, if they hit "yes, it's fine" then update the database.
你总是可以让他们检查下载是否符合他们的预期,如果他们点击“是的,没关系”,然后更新数据库。
Edited:编辑:响应OP的评论。
Thanks, but you can't depend on the users cooperativeness. Because they also have to pay for the download, it is better that I have all the controll.I think I will then update the database when the script is accessed. That seems to be the most reliable then.
谢谢,但你不能依赖用户的合作。因为他们下载也是要付费的,所以最好我有所有的控制权。我想我会在访问脚本时更新数据库。那看来是最靠谱的了。
How about using an Ajax control to initiate -and maintain- the download, and, on completion verifying its integrity and running an update to your db?
如何使用 Ajax 控件启动和维护下载,并在完成后验证其完整性并运行对数据库的更新?
I'd suggest not automatically assuming your customers are going to rip you off, though, whatever you end up choosing. Asking them nicely 'did it work for you?' and, if not, leading to a bug-report might be useful for you and them.
不过,我建议不要自动假设您的客户会欺骗您,无论您最终选择什么。很好地问他们“它对你有用吗?” 如果没有,导致错误报告可能对您和他们有用。
But, regardless, while some of your users might say 'no' just for the extra copy you have to balance the cost of that against the cost of your increased workload to prevent its happening. If the cost of maintaining 'honesty' exceeds the potential/likely cost of their taking an extra copy, then there's little point.
但是,无论如何,虽然您的一些用户可能会说“不”,只是因为额外的副本,但您必须平衡其成本与增加的工作量的成本,以防止其发生。如果保持“诚实”的成本超过了他们获取额外副本的潜在/可能成本,那么就没有意义了。
回答by Ben Rowe
I don't think it's possible via php to know how many bites have been sent out (and actually downloaded via the client), since there's no way to know if the user has cancelled the download or received the entire file.
我认为无法通过 php 知道发送了多少字节(实际上是通过客户端下载的),因为无法知道用户是否取消了下载或接收了整个文件。
回答by Mike Castro Demaria
There is a solution if you are mixing php (for server side call ) an javascript (for client complete call) .
如果您将 php(用于服务器端调用)和 javascript(用于客户端完整调用)混合使用,则有一个解决方案。
Look this answer on how to Detect when browser receives file download
查看有关如何检测浏览器何时接收文件下载的答案
I'm pretty sure you can have a good result like this. I hope this help others, Mike
我很确定你能得到这样的好结果。我希望这能帮助其他人,迈克
回答by Francois
The following code works. If the download is stopped by the client, the database is not updated and the link can fire again.
以下代码有效。如果客户端停止下载,则数据库不会更新,链接可能会再次触发。
$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;

