2013-10-22 102 views
4

我處於一種情況,當我必須實現從Web服務器下載大文件(最多4GB):Apache 2.4.4通過HTTP協議。我嘗試了幾種方法,但最好的解決方案看起來是X-SendFile模塊的用法。HTTP文件下載:監控下載進度

由於我提供文件上傳的進度條,因此我需要具有相同的文件下載功能。所以這裏是我的問題:

  • 是否有任何方式,包括解決方法,實現文件下載進度監控?
  • 有什麼辦法,包括解決方法,來計算文件下載傳輸速度?
  • 有沒有比使用X-Sendfile模塊更好地從Web服務器提供文件下載的方法?

是否有更好的文件下載選項一般,這將允許我監視文件下載進度?它可以是客戶端(JavaScript)或服務器解決方案(PHP)。有沒有任何特定的Web服務器允許這個?

目前我使用:

  • 阿帕奇
  • Ubuntu的

感謝2.4.4很多次。

+1

可以在PHP中使用捲曲。 http://stackoverflow.com/questions/13958303/curl-download-progress-in-php –

+0

你是否有能力從你的服務器流式傳輸文件 - 或者你正在下載單個文件嗎? –

+0

@ webbod,許多文件將從服務器上下載。換句話說,文件下載和上傳將是服務器的主要功能。由於我在控制服務器,我可以決定任何形式的文件下載。我試圖通過PHP進行下載,但是這對文件大小和下載的文件數量造成了限制。因此我嘗試了X-SendFile,它看起來不錯。但是,如果流媒體是要走的路,我很樂意僞造X-SendFile –

回答

4

2想法(未驗證):

第一:

而是將常規文件的鏈接(要下載)在你的網頁鏈接的地方像.../dowanload.php的這可能看起來像這樣:

<?php 

    // download.php file 
    session_start(); // if needed 

    $filename = $_GET['filename']); 

    header('Content-type: text/plain'); // use any MIME you want here 
    header('Content-Disposition: attachment; filename="' . htmlspecialchars($filename) . '"'); 
    header('Pragma: no-cache'); 

    // of course add some error handling 

    $filename = 'c:/php/php.ini'; 

    $handle = fopen($filename, 'rb'); 

    // do not use file_get_contents as you've said files are up to 4GB - so read in chunks 
    while($chunk = fread($handle, 1000)) // chunk size may depend on your filesize 
    { 
     echo $chunk; 
     flush(); 
     // write progress info to the DB, or session variable in order to update progress bar 
    } 

    fclose($handle); 
?> 

這樣你可以留意你的下載過程。與此同時,您可以將進度信息寫入DB/session var,並使用AJAX從DB/session var更新進度條閱讀狀態,當然這些AJAX會輪詢讀取進度信息的腳本。

這是非常簡單的,但我認爲它可能會工作,只要你想。

二:

的Apache 2.4具有內置的Lua語言:

我敢打賭,你可以嘗試寫LUA Apache的處理程序,將監視你的下載 - 發送進度到數據庫和更新進度條使用PHP/AJAX採取公關從數據庫中獲取信息。

同樣 - 存在用於perl模塊和甚至蟒(但不爲贏)

+0

奇怪的URL可以使用mod_rewrite隱藏。外部世界不需要知道download.php腳本。 – Palec

+0

而不是mod_lua你可以使用mod_perl,它不處於實驗狀態。 – Palec

+0

@Palec:同意這兩個意見 - 可以這樣做 – Artur

2

我看到的主要問題在於: 在一個PHP + apache的溶液輸出緩衝可被放置在多個位置:

瀏覽器< = 1 =>阿帕奇< = 2 => PHP處理程序< = 3 => PHP解釋 過程

您甲腎上腺素編輯來控制第一個緩衝區。但直接從PHP是不可能的。

可能的解決方案:

1)你可以寫自己的小守護它的主要功能將只發送文件並運行它在另一個比例如80端口8880。並從那裏處理下載文件和監視輸出緩衝區。 你的輸出緩衝區將是唯一的一個,則可以控制它:

瀏覽器< = 1 => PHP解釋過程

2)也可以採取mod_lua並直接從apache的控制輸出緩衝器。

3)亦可以採取nginx和使用控制nginx的輸出緩衝器內置在Perl(它是穩定的)

4)嘗試直接使用PHP Built-in web server和控制PHP輸出緩衝器。我無法說出它是如何穩定的,對不起。但你可以試試。 ;)

我認爲nginx + php +內置的perl是更穩定和強大的解決方案。 但是,您可以選擇,也可以使用非列表中的其他解決方案。我會按照這個話題,等待你的最終解決方案。

2

以較短的時間間隔讀取和寫入數據庫會導致性能下降。

我會建議使用session(增加循環中發送的數據的值),你可以安全地通過另一個php文件關閉數據,你可以返回數據爲JSON,可以使用javascript函數/插件。

+0

好主意。我也一樣。不過,我遇到了一個意想不到的問題:當主PHP下載腳本正在運行時,監控PHP腳本不會被AJAX調用執行。我長期堅持並測試它。但是,AJAX監控腳本顯然只在當前沒有其他PHP腳本運行時運行。 [見我的另一篇文章](http://stackoverflow.com/questions/19683192/ajax-wont-call-its-php-script-while-another-php-script-is-running) –

+0

我已經嘗試了很多方法,他們都有某種問題。使用'fopen()''fread()''print()'的方法對我最好,對文件大小沒有限制。因此,我將這個答案標記爲有用的答案,就像接受的答案一樣,並用我的賞金獎勵它。 –

-1

如果你使用的PHP版本> = 5.4那麼這可以幫助你http://www.php.net/manual/en/session.upload-progress.php

+0

嗨,謝謝你的建議。我意識到這一點,實際上我已經實施了。唯一的問題是,雖然它適用於上傳,但無法下載。因此,我尋找替代解決方案。 –