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 相关文章推荐
自己动手做一个SQL解释器
Oct 09 PHP
来自PHP.NET的入门教程
Oct 09 PHP
php array_push()数组函数:将一个或多个单元压入数组的末尾(入栈)
Jul 12 PHP
深入理解curl类,可用于模拟get,post和curl下载
Jun 08 PHP
Zend Framework框架路由机制代码分析
Mar 22 PHP
php构造函数与析构函数
Apr 23 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
Sep 11 PHP
php并发加锁示例
Oct 17 PHP
php简单计算年龄的方法(周岁与虚岁)
Dec 06 PHP
php取出数组单个值的方法
Mar 12 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
Jun 13 PHP
Thinkphp 框架扩展之应用模式实现方法分析
Apr 27 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
中英文字符串翻转函数
2008/12/09 PHP
PHP exif扩展方法开启详解
2014/07/28 PHP
PHP设计模式之单例模式原理与实现方法分析
2018/04/25 PHP
Laravel Eloquent ORM 多条件查询的例子
2019/10/10 PHP
JavaScript与C# Windows应用程序交互方法
2007/06/29 Javascript
利用javascript解决图片缩放及其优化的代码
2012/05/23 Javascript
jquery移除、绑定、触发元素事件使用示例详解
2014/04/10 Javascript
控制台报错object is not a function的解决方法
2014/08/24 Javascript
JQuery调用绑定click事件的3种写法
2015/03/28 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
AngularJS实现ajax请求的方法
2016/11/22 Javascript
Angular 利用路由跳转到指定页面的指定位置方法
2018/08/31 Javascript
node+express框架中连接使用mysql(经验总结)
2018/11/10 Javascript
微信小程序实现保存图片到相册功能
2018/11/30 Javascript
jQuery实现判断滚动条滚动到document底部的方法分析
2019/08/27 jQuery
Vertx基于EventBus发送接受自定义对象
2020/11/16 Javascript
跟老齐学Python之Import 模块
2014/10/13 Python
python实现向ppt文件里插入新幻灯片页面的方法
2015/04/28 Python
Python编程之列表操作实例详解【创建、使用、更新、删除】
2017/07/22 Python
python里使用正则的findall函数的实例详解
2017/10/19 Python
django页面跳转问题及注意事项
2019/07/18 Python
加拿大著名时装品牌:SOIA & KYO
2016/08/23 全球购物
ECOSUSI官网:女式皮革背包
2019/09/27 全球购物
JAVA的事件委托机制和垃圾回收机制
2014/09/07 面试题
国际商务专业学生个人的自我评价
2013/09/28 职场文书
银行会计业务的个人自我评价
2013/11/02 职场文书
大学生职业生涯规划书前言
2014/01/09 职场文书
荷叶圆圆教学反思
2014/02/01 职场文书
消防安全管理制度
2014/02/01 职场文书
大学生个人自荐信
2014/02/24 职场文书
教师节促销方案
2014/03/22 职场文书
白血病捐款倡议书
2014/05/14 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
五四青年节比赛演讲稿
2015/03/18 职场文书
工资证明范本
2015/06/12 职场文书
小学生法制教育心得体会
2016/01/14 职场文书