有关PHP下载的一次大坑
起因
采用PHP下载文件,刚开始用英文名字一切正常,后来换成中文名字,或者不能下载,或者是下载内容空白,或者是下载文件名无中文,于是百度了很多方法,但是都没有根本解决上面的所有问题。
借鉴
- 代码一:
header("Content-type: application/octet-stream");
header("Accept-Ranges: bytes");//按照字节大小返回
header("Accept-Length: $FileSize");//返回文件大小
header('Content-disposition:attachment;filename=' . basename($tmp_file));
$FileSize=filesize($tmp_file);
$File=fopen($tmp_file,"r");//打开文件
$FileBuff=512;
while($FileSize>=0){
$FileSize-=$FileBuff;
echo fread($File,$FileBuff);
}
fclose($File);
没达到要求。
2. 代码二
*ob_clean();//清除一下缓冲区
$_name = $filename; //上面已经转码过了
$filepath = $path_dir.$_name;
//$filename = mb_convert_encoding($filename,'UTF-8','GBK'); //生成的文件名称转换一下编码
//info($filename);exit;
//$filename = urlencode($filename);
//var_dump(urlencode($filename));exit;
$file=fopen($filepath,"r");
header("Content-type:text/html;charset=utf-8");
header("Content-Type: application/octet-stream");
header("Accept-Ranges: bytes");
header("Accept-Length: ".filesize($filepath));
header("Content-Disposition: attachment; filename=" . $filename);
echo fread($file,filesize($filepath));
fclose($file);*
没起作用
3. 代码三,自己原来的代码,最简练
header('Content-Type:text/html;charset=utf-8');
header('Content-disposition:attachment;filename=' . basename($filename));
$filesize = filesize($tmp_file);
readfile($tmp_file);
header('Content-length:' . $filesize);
调试
- 期间,无论怎么转换$filename,都不行,比如采用
$filename = mb_convert_encoding($filename,'UTF-8','GBK');
或者采用
$filename = mb_convert_encoding($filename,'GBK','UTF-8');
都不成功。
- 后来,干脆自己先直接起了一个中文名字下载,居然成功了!代码如下:
header('Content-Type:text/html;charset=utf-8');
header('Content-disposition:attachment;filename=' . '调试.doc');
$filesize = filesize($tmp_file);
readfile($tmp_file);
header('Content-length:' . $filesize);
结论
basename是一个大坑,对于中文给转换没啦!所以中文文件名要自己生成,别懒得省事,直接用它提取文件名,它能给你过滤掉中文。
证据
验证代码如下:
<?php
header("Content-type:text/html;charset=utf-8");
$s = "设计ss123.doc";
$r = basename($s);
var_dump($s);
var_dump($r);
?>
输出结果:
string(15) "设计ss123.doc" string(9) "ss123.doc"
中文被“吃”啦,或者自己“飞出锅“了!