2009-10-13 111 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

敢肯定,你可以有一個很好的結果是這樣的。 我希望這幫助了別人, 邁克