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 mysql数据库操作分页类
Jun 04 PHP
CakePHP去除默认显示的标题及图标的方法
Oct 22 PHP
php 传值赋值与引用赋值的区别
Dec 29 PHP
php存储过程调用实例代码
Feb 03 PHP
php统计文章排行示例
Mar 04 PHP
ThinkPHP添加更新标签的方法
Dec 05 PHP
PHP函数extension_loaded()用法实例
Jan 19 PHP
php将HTML表格每行每列转为数组实现采集表格数据的方法
Apr 03 PHP
php实现可逆加密的方法
Aug 11 PHP
php连接mysql数据库
Mar 21 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
Apr 12 PHP
分享8个Laravel模型时间戳使用技巧小结
Feb 12 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
菜鸟修复电子管记
2021/03/02 无线电
咖啡的植物学知识
2021/03/03 咖啡文化
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
PHP数组遍历知识汇总(包含遍历方法、数组指针操作函数、数组遍历测速)
2014/07/05 PHP
PHP单例模式详细介绍
2015/07/01 PHP
JavaScript代码复用模式实例分析
2012/12/02 Javascript
Javascript new Date().valueOf()的作用与时间戳由来详解
2013/04/24 Javascript
js实现两个值相加alert出来精确到指定位
2013/09/25 Javascript
解析JSON对象与字符串之间的相互转换
2013/12/18 Javascript
Javascript检查图片大小不要让大图片撑破页面
2014/11/04 Javascript
基于jQuery+JSON的省市二三级联动效果
2015/06/05 Javascript
JS基于Mootools实现的个性菜单效果代码
2015/10/21 Javascript
HTML5 js实现拖拉上传文件功能
2020/11/20 Javascript
基于Vue实现微信小程序的图文编辑器
2018/07/25 Javascript
通过函数作用域和块级作用域看javascript的作用域链
2018/08/05 Javascript
JS Ajax请求会话过期处理问题解决方法分析
2019/11/16 Javascript
[01:06:07]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS CIS
2014/05/22 DOTA
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中的推导式使用详解
2015/06/03 Python
Python实现的简单dns查询功能示例
2017/05/24 Python
Python人脸识别初探
2017/12/21 Python
详解python中递归函数
2019/04/16 Python
django做form表单的数据验证过程详解
2019/07/26 Python
Django 迁移、操作数据库的方法
2019/08/02 Python
Django在admin后台集成TinyMCE富文本编辑器的例子
2019/08/09 Python
Pycharm调试程序技巧小结
2020/08/08 Python
Django+Django-Celery+Celery的整合实战
2021/01/20 Python
美国隐形眼镜销售网站:ContactsDirect
2017/10/28 全球购物
TripAdvisor瑞典:全球领先的旅游网站
2017/12/11 全球购物
传播学专业毕业生自荐信
2013/11/04 职场文书
篮球比赛拉拉队口号
2014/06/10 职场文书
个人批评与自我批评范文
2014/10/17 职场文书
中学生自我评价范文
2015/03/03 职场文书
时尚女魔头观后感
2015/06/04 职场文书
Ubuntu Server 安装Tomcat并配置systemctl
2022/04/28 Servers
GoFrame gredis缓存DoVar Conn连接对象 自动序列化GoFrame gredisDo/DoVar方法Conn连接对象自动序列化/反序列化总结
2022/06/14 Golang