php做下载文件的实现代码及文件名中乱码解决方法


Posted in PHP onFebruary 03, 2011

最近有人问我做下载文件的方法,对于php方法如下:

<?php 
header("Content-Type: application/force-download"); 
header("Content-Disposition: attachment; filename=ins.jpg"); 
readfile("imgs/test_Zoom.jpg"); 
?>

第一行代码是强制下载;
第二行代码是给下载的内容指定一个名字;
第三行代码是把下载的内容读进文件中。
如何在PHP下载文件名中解决乱码
通过把Content-Type设置为application/octet-stream,可以把动态生成的内容当作文件来下载,相信这个大家都会。那么用Content-Disposition设置下载的文件名,这个也有不少人知道吧。基本上,下载程序都是这么写的:
<?php 
$filename = "document.txt"; 
header('Content-Type: application/octet-stream'); 
header('Content-Disposition: attachment; filename=' . $filename); 
print "Hello!"; 
?>

这样用浏览器打开之后,就可以下载document.txt。
但是,如果$filename是UTF-8编码的,有些浏览器就无法正常处理了。比如把上面那个程序稍稍改一下:
<?php 
$filename = "中文 文件名.txt"; 
header('Content-Type: application/octet-stream'); 
header('Content-Disposition: attachment; filename=' . $filename); 
print "Hello!"; 
?>

把程序保存成UTF-8编码再访问,IE6下载的文件名就会乱码。 FF3下下载的文件名就只有“中文”两个字。Opera 9下一切正常。
输出的header实际上是这样子:
Content-Disposition: attachment; filename=中文 文件名.txt其实按照RFC2231的定义,多语言编码的Content-Disposition应该这么定义:
Content-Disposition: attachment; filename*="utf8''%E4%B8%AD%E6%96%87%20%E6%96%87%E4%BB%B6%E5%90%8D.txt"

即:
filename后面的等号之前要加 *
filename的值用单引号分成三段,分别是字符集(utf8)、语言(空)和urlencode过的文件名。
最好加上双引号,否则文件名中空格后面的部分在Firefox中显示不出来
注意urlencode的结果与php的urlencode函数结果不太相同,php的urlencode会把空格替换成+,而这里需要替换成%20
经过试验,发现几种主流浏览器的支持情况如下:
IE6 attachment; filename="<URL编码之后的UTF-8文件名>"
FF3 attachment; filename="UTF-8文件名"
attachment; filename*="utf8''<URL编码之后的UTF-8文件名>"
O9 attachment; filename="UTF-8文件名"
Safari3(Win) 貌似不支持?上述方法都不行
这样看来,程序必须得这样写才能支持所有主流浏览器:
<?php 
$ua = $_SERVER["HTTP_USER_AGENT"]; 
$filename = "中文 文件名.txt"; 
$encoded_filename = urlencode($filename); 
$encoded_filename = str_replace("+", "%20", $encoded_filename); 
header('Content-Type: application/octet-stream'); 
if (preg_match("/MSIE/", $ua)) { 
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"'); 
} else if (preg_match("/Firefox/", $ua)) { 
header('Content-Disposition: attachment; filename*="utf8\'\'' . $filename . '"'); 
} else { 
header('Content-Disposition: attachment; filename="' . $filename . '"'); 
} 
print 'ABC'; 
?>
PHP 相关文章推荐
如何在PHP中进行身份认证
Oct 09 PHP
PHP+Tidy-完美的XHTML纠错+过滤
Apr 10 PHP
PHP5中使用DOM控制XML实现代码
May 07 PHP
10条PHP高级技巧[修正版]
Aug 02 PHP
探讨php中header的用法详解
Jun 07 PHP
php过滤XSS攻击的函数
Nov 12 PHP
php无限极分类递归排序实现方法
Nov 11 PHP
PHP实现删除字符串中任何字符的函数
Aug 11 PHP
PHP反射API示例分享
Oct 08 PHP
PHP写的简单数字验证码实例
May 23 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
Mar 24 PHP
thinkphp框架实现路由重定义简化url访问地址的方法分析
Apr 04 PHP
PHP+SQL 注入攻击的技术实现以及预防办法
Jan 27 #PHP
php5 apache 2.2 webservice 创建与配置(java)
Jan 27 #PHP
使用XDebug调试及单元测试覆盖率分析
Jan 27 #PHP
仿AS3实现PHP 事件机制实现代码
Jan 27 #PHP
PHP 命名空间实例说明
Jan 27 #PHP
PHP中利用substr_replace将指定两位置之间的字符替换为*号
Jan 27 #PHP
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
Jan 27 #PHP
You might like
一篇不错的PHP基础学习笔记
2007/03/18 PHP
PHP封装的多文件上传类实例与用法详解
2017/02/07 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
2017/07/26 PHP
(JS实现)MapBar中坐标的加密和解密的脚本
2007/05/16 Javascript
formValidator3.3的ajaxValidator一些异常分析
2011/07/12 Javascript
在jQuery ajax中按钮button和submit的区别分析
2012/10/07 Javascript
JS声明变量背后的编译原理剖析
2012/12/28 Javascript
javascript和jquery修改a标签的href属性
2013/12/16 Javascript
js图片闪动特效可以控制间隔时间如几分钟闪动一下
2014/08/12 Javascript
jquery实现表单输入时提示文字滑动向上效果
2015/08/10 Javascript
text-align:justify实现文本两端对齐 兼容IE
2015/08/19 Javascript
jQuery css() 方法动态修改CSS属性
2016/09/25 Javascript
详解ECharts使用心得总结
2016/12/06 Javascript
在node中如何使用 ES6
2017/04/22 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
JavaScript判断变量名是否存在数组中的实例
2017/12/28 Javascript
JavaScript实现读取与输出XML文件数据的方法示例
2018/06/05 Javascript
jQuery层叠选择器用法实例分析
2019/06/28 jQuery
手把手教您实现react异步加载高阶组件
2020/04/07 Javascript
用Python输出一个杨辉三角的例子
2014/06/13 Python
Python实现类继承实例
2014/07/04 Python
Python contextlib模块使用示例
2015/02/18 Python
Python实现批量转换文件编码的方法
2015/07/28 Python
python遍历文件夹下所有excel文件
2018/01/03 Python
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
解决pip install的时候报错timed out的问题
2018/06/12 Python
使用Selenium破解新浪微博的四宫格验证码
2018/10/19 Python
Python构建图像分类识别器的方法
2019/01/12 Python
Python中的引用知识点总结
2019/05/20 Python
python 操作mysql数据中fetchone()和fetchall()方式
2020/05/15 Python
python 读取.nii格式图像实例
2020/07/01 Python
python绘图模块之利用turtle画图
2021/02/12 Python
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
家具厂厂长岗位职责
2014/01/01 职场文书
安全生产年活动总结
2014/08/29 职场文书
机关保密工作承诺书
2015/05/04 职场文书