我目前正在创建一个功能,允许从远程服务器下载文件。我的脚本适用于所有需要的文件类型,但由于某种原因它不适用于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'文件呢? –