2017-03-01 93 views
3

我目前正在創建一個功能,允許從遠程服務器下載文件。我的腳本適用於所有需要的文件類型,但由於某種原因它不適用於msg文件(它下載空文件(0K))。順便說一句,在Chrome和IE中同樣的行爲。我認爲問題是與文件大小,所以我已經測試下載大型壓縮文件,它也工作正常,似乎只有味精文件我有問題。如何使用PHP下載msg文件

我的腳本:

我做錯了嗎?

P.S.我認爲可能的解決方案是在上傳過程中存檔(zip).msg文件,然後將其下載爲.zip,但我正在尋找更好的解決方案。

+0

不是一個答案,但對於你的腳本一個建議:你應該清理你的'$ _GET [ 'FILE_NAME']',以避免有人通過這樣的東西'../ passwd' –

+2

您可以從遠程服務器下載PHP腳本運行所在的服務器的.msg文件,例如:用'wget http:// mypath/uploads/test.msg'?我用本地文件測試了你的腳本,例如。 '$ file_url ='test.msg';',這是在這裏工作,所以我懷疑是從遠程服務器獲取它的問題。您也可以檢查'readfile'的返回值 - 如果它是'false',則讀取文件時會出錯。 –

+0

我測試了腳本,它下載了遠程'msg'文件。 nginx + php 5.6。你確定腳本有權下載文件嗎?如果它是'mypath'中的服務器,那不會提供'.msg'文件呢? –

回答

3

擴展my comment到一個答案:

我有一個本地文件,例如測試腳本。 $file_url = 'test.msg';,這是在這裏工作。所以我懷疑是從遠程服務器獲取文件時出現問題。你能否通過PHP以外的其他方式從運行PHP腳本的服務器下載遠程.msg文件,例如。與wget http://mypath/uploads/test.msg?您還可以檢查readfile的返回值 - if it is false, there is an error reading the file。如果您無法下載該文件或者readfile返回false,那麼問題不在您的代碼中,而是您必須首先解決的服務器配置或連接問題。

關於你的代碼:你應該清理你的$_GET['file_name'],以避免有人通過像../passwd這樣的東西。

2

嘗試使用其他內容類型:

header("Content-Type: application/download"); 
+0

我剛剛嘗試使用另一個標題,但仍然沒有喜悅,同樣的問題! –

+0

@DenissMuntjans更新了嘗試這一個:) – EL3PHANTEN

+0

仍然一樣,它下載空msg文件! –

3

您正在嘗試使用readfile一個URL文件的位置,這是可能的,只有fopen wrappers已啓用。

從PHP readfile

提示的URL可如果fopen wrappers 已啓用作爲具有這種功能的文件名。有關如何 指定文件名的更多詳細信息,請參閱fopen()。有關 可能提供的有關各種包裝具有哪些功能的信息的鏈接,請參閱Supported Protocols and Wrappers的鏈接, 關於其使用的註釋以及有關任何預定義變量的信息。

這不是安全的,你應該使用本地系統路徑insted的這樣一個URL:

// Get parameter form html page 
if(isset($_GET['file_name'])) $file_name = $_GET['file_name']; 

$file_name = str_replace('"', '\\"', $file_name); 
//$file_url = 'http://mypath/uploads/' . $file_name; 
// The script is located to one level up directory of the uploads directory 
// You can change this to fit your script and uploads directory locations 
$uploads_local_path = __DIR__.'/uploads/'; 
$file_path = $uploads_local_path.$file_name; 

header('Content-Type: application/octet-stream'); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
header("Content-Transfer-Encoding: Binary"); 

readfile($file_path); 
exit; 

,現在它的工作原理,並下載該文件。請注意並且有uploads目錄的正確路徑位置。

你甚至可以嘗試我的地方例如基於您的代碼在這裏和下載文件:http://zikro.gr/dbg/php/dl-file/

直接鏈接到下載腳本,你可以嘗試:http://zikro.gr/dbg/php/dl-file/dodl.php?file_name=1011191_orig.png

1

嘗試添加用戶代理並接受您的請求中的所有MIME類型。通過使用捲曲:

// Get parameter form html page 
if(isset($_GET['file_name'])) $file_name = $_GET['file_name']; 

$file_name = str_replace('"', '\\"', $file_name); 
$file_url = 'http://mypath/uploads/' . $file_name; 

header('Content-Type: application/octet-stream'); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
header("Content-Transfer-Encoding: Binary"); 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $file_url); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0'); 
$headerData[] = 'Accept: */*'; 
curl_setopt($ch, CURLOPT_HTTPHEADER, $headerData); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$data = curl_exec ($ch); 
$error = curl_error($ch); 
curl_close($ch); 
echo $data; 
exit; 
1

試試吧

// Get parameter form html page 
if(isset($_GET['file_name'])) $file_name = $_GET['file_name']; 

$file_name = str_replace('"', '\\"', $file_name); 
$file_url = 'http://mypath/uploads/' . $file_name; 

header("Content-Type: application/download"); 
header("Content-disposition: attachment; filename=\"".$file_name."\""); 
header("Content-Transfer-Encoding: Binary"); 

readfile($file_url); 
exit; 
0

我認爲你必須指定Content-lenght標題,我認爲禁用緩存也可能有幫助。

例如:

header("Content-length: " . strlen($output); // tells file size 
header("Pragma: no-cache"); 
header("Expires: 0");