我目前正在創建一個功能,允許從遠程服務器下載文件。我的腳本適用於所有需要的文件類型,但由於某種原因它不適用於msg文件(它下載空文件(0K))。順便說一句,在Chrome和IE中同樣的行爲。我認爲問題是與文件大小,所以我已經測試下載大型壓縮文件,它也工作正常,似乎只有味精文件我有問題。如何使用PHP下載msg文件
我的腳本:
我做錯了嗎?
P.S.我認爲可能的解決方案是在上傳過程中存檔(zip).msg文件,然後將其下載爲.zip,但我正在尋找更好的解決方案。
我目前正在創建一個功能,允許從遠程服務器下載文件。我的腳本適用於所有需要的文件類型,但由於某種原因它不適用於msg文件(它下載空文件(0K))。順便說一句,在Chrome和IE中同樣的行爲。我認爲問題是與文件大小,所以我已經測試下載大型壓縮文件,它也工作正常,似乎只有味精文件我有問題。如何使用PHP下載msg文件
我的腳本:
我做錯了嗎?
P.S.我認爲可能的解決方案是在上傳過程中存檔(zip).msg文件,然後將其下載爲.zip,但我正在尋找更好的解決方案。
擴展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
這樣的東西。
嘗試使用其他內容類型:
header("Content-Type: application/download");
您正在嘗試使用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
可能是一個愚蠢的問題,但是,你有沒有嘗試了簡單
$fileurl="http://example.com/file.msg";
$fileContent = file_get_contents($fileurl);
file_put_contents($saveDir.$fileName, $fileContent);
嘗試添加用戶代理並接受您的請求中的所有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;
試試吧
// 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;
我認爲你必須指定Content-lenght標題,我認爲禁用緩存也可能有幫助。
例如:
header("Content-length: " . strlen($output); // tells file size
header("Pragma: no-cache");
header("Expires: 0");
不是一個答案,但對於你的腳本一個建議:你應該清理你的'$ _GET [ 'FILE_NAME']',以避免有人通過這樣的東西'../ passwd' –
您可以從遠程服務器下載PHP腳本運行所在的服務器的.msg文件,例如:用'wget http:// mypath/uploads/test.msg'?我用本地文件測試了你的腳本,例如。 '$ file_url ='test.msg';',這是在這裏工作,所以我懷疑是從遠程服務器獲取它的問題。您也可以檢查'readfile'的返回值 - 如果它是'false',則讀取文件時會出錯。 –
我測試了腳本,它下載了遠程'msg'文件。 nginx + php 5.6。你確定腳本有權下載文件嗎?如果它是'mypath'中的服務器,那不會提供'.msg'文件呢? –