如何用PHP下载msg文件

时间:2017-03-01 14:48:28

标签: php

我目前正在创建一项允许从远程服务器下载文件的功能。我的脚本适用于所需的所有文件类型,但由于某种原因它不适用于msg文件(它下载空文件(0K))。顺便说一下Chrome和IE中的行为相同。我认为问题在于文件大小,所以我已经测试过下载大型zip文件,它也运行正常,似乎只有msg文件我遇到了问题。

我的剧本:

// 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");

readfile($file_url);
exit;

我做错了什么?

P.S。我认为可行的解决方案是在上传过程中存档(zip).msg文件,然后将其下载为.zip,但我正在寻找更好的解决方案。

7 个答案:

答案 0 :(得分:3)

您尝试将readfile与URL文件位置一起使用,只有在fopen wrappers启用后才可以使用。

来自PHP readfile

  

提示如果fopen wrappers,则可以使用此功能将URL用作文件名   已启用。有关如何操作的详细信息,请参阅fopen()   指定文件名。请参阅Supported Protocols and Wrappers   链接到有关各种包装器具有哪些功能的信息,   关于它们的使用和它们的任何预定义变量的信息的注释   可能会提供。

这不安全,你应该使用像这样的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 :(得分: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 :(得分:2)

尝试使用其他内容类型:

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

答案 3 :(得分:1)

可能是一个愚蠢的问题,但是,你试过一个简单的

$fileurl="http://example.com/file.msg";
$fileContent = file_get_contents($fileurl);
file_put_contents($saveDir.$fileName, $fileContent);

http://php.net/manual/en/function.file-get-contents.php

http://php.net/manual/en/function.file-put-contents.php

答案 4 :(得分:1)

尝试添加用户代理并接受请求中的所有MIME类型..使用cURL:

// 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;

答案 5 :(得分: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;

答案 6 :(得分:0)

我认为您必须指定Content-lenght标头,我认为禁用缓存也可能有所帮助。

例如:

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