这几天写项目,遇到一个问题,一般的文件下载还好说,但是如果是中文且有多种格式的文件下载就比较棘手,调了很久的BUG,
终于完成,其中需要注意以下几点:
1.对于文件名是中文的文件,要记得转码,防止中文乱码的发生,因为大部分的主机的编码是GB2312的,而我们用的是UTF-8,
所以在操作之前要用iconv()函数进行转码,防止找不到文件而报错。
2.需要对所要下载的文件的格式进行判断,根据格式再写header()函数。
具体代码如下:
<?php
header("Content-type:text/html;charset=utf-8");
$filename = "大学英语选课说明.docx"; //文件名
$filename = iconv("utf-8","gb2312//IGNORE",$filename); //转码
$file = "upload/".$filename; //文件路径
$len = filesize($file); //文件大小
$file_extension = strtolower(substr(strrchr($filename,"."),1)); //文件后缀名
switch( $file_extension ) //判断文件类型
{
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "docx":
case "doc": $ctype="application/msword"; break;
case "xls": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpeg":
case "jpg": $ctype="image/jpg"; break;
case "mp3": $ctype="audio/mpeg"; break;
case "wav": $ctype="audio/x-wav"; break;
case "mpeg":
case "mpg":
case "mpe": $ctype="video/mpeg"; break;
case "mov": $ctype="video/quicktime"; break;
case "avi": $ctype="video/x-msvideo"; break;
case "php":
case "htm":
case "html": die("<b>Cannot be used for ". $file_extension ." files!</b>"); break;
default: $ctype="application/force-download";
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: $ctype");
$header="Content-Disposition: attachment; filename=".$filename.";";
header($header);
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".$len);
readfile($file);
?>
对于适配不同浏览器,避免发生中文乱码错误,本人在网上找到一段代码,可以避免,代码如下:
<?php
<span style="white-space:pre"> </span>$ua = $_SERVER["HTTP_USER_AGENT"];
<span style="white-space:pre"> </span>$filename = "中文 文件名.txt";
<span style="white-space:pre"> </span>$encoded_filename = urlencode($filename);
<span style="white-space:pre"> </span>$encoded_filename = str_replace("+", "%20", $encoded_filename);
<span style="white-space:pre"> </span>header('Content-Type: application/octet-stream');
<span style="white-space:pre"> </span>if (preg_match("/MSIE/", $ua)) {
<span style="white-space:pre"> </span>header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
<span style="white-space:pre"> </span>} else if (preg_match("/Firefox/", $ua)) {
<span style="white-space:pre"> </span>header('Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"');
<span style="white-space:pre"> </span>} else {
<span style="white-space:pre"> </span>header('Content-Disposition: attachment; filename="' . $filename . '"');
<span style="white-space:pre"> </span>}
?>
我没有用这段代码的原因是上面我写的代码我试了一下如:Firefox,IE,Opera,360等这些浏览器,没有发生因为浏览器问题
产生的乱码错误,我认为,转码后中文乱码的问题基本就解决了。
本人经验,仅供参考!