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函数
Dec 06 PHP
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
Nov 01 PHP
基于Zend的Captcha机制的应用
May 02 PHP
mongo Table类文件 获取MongoCursor(游标)的实现方法分析
Jul 01 PHP
PHP中把数据库查询结果输出为json格式简单实例
Apr 09 PHP
PHP查找数值数组中不重复最大和最小的10个数的方法
Apr 20 PHP
php传值赋值和传地址赋值用法实例分析
Jun 20 PHP
php猜单词游戏
Sep 29 PHP
php面向对象编程self和static的区别
May 08 PHP
yii2带搜索功能的下拉框实例详解
May 12 PHP
php7安装yar扩展的方法详解
Aug 03 PHP
php微信公众号开发之关键词回复
Oct 20 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
header跳转和include包含问题详解
2012/09/08 PHP
php文件服务实现虚拟挂载其他目录示例
2014/04/17 PHP
php中this关键字用法分析
2016/12/07 PHP
php和js实现根据子网掩码和ip计算子网功能示例
2019/11/09 PHP
jQuery动态添加删除select项(实现代码)
2013/09/03 Javascript
jquery 页面滚动到指定DIV实现代码
2013/09/25 Javascript
javascript中var的重要性分析
2015/02/11 Javascript
JavaScript中的fontsize()方法使用详解
2015/06/08 Javascript
JavaScript缓冲运动实现方法(2则示例)
2016/01/08 Javascript
JS判断元素是否在数组内的实现代码
2016/03/30 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
VUE 使用中踩过的坑
2018/02/08 Javascript
如何解决vue2.0下IE浏览器白屏问题
2018/09/13 Javascript
微信小程序实现商城倒计时
2020/11/01 Javascript
JS实现水平遍历和嵌套递归操作示例
2019/08/15 Javascript
微信小程序实现打开并下载服务器上面的pdf文件到手机
2019/09/20 Javascript
微信小程序自定义导航栏(模板化)
2019/11/15 Javascript
[02:53]DOTA2亚洲邀请赛 NewBee战队巡礼
2015/02/03 DOTA
python将txt文件读取为字典的示例
2018/12/22 Python
Django实现CAS+OAuth2的方法示例
2019/10/30 Python
Python读取VOC中的xml目标框实例
2020/03/10 Python
Pycharm导入anaconda环境的教程图解
2020/07/31 Python
使用Python提取文本中含有特定字符串的方法示例
2020/12/09 Python
澳大利亚足球鞋和服装购物网站:Ultra Football
2018/10/11 全球购物
美国沙龙美发产品购物网站:Hair.com by L’Oreal
2020/11/09 全球购物
Unix如何添加新的用户
2014/08/20 面试题
项目合作协议书
2014/04/16 职场文书
2014年销售工作总结
2014/12/01 职场文书
2014年内部审计工作总结
2014/12/09 职场文书
员工辞退通知书
2015/04/17 职场文书
教您怎么制定西餐厅运营方案 ?
2019/07/05 职场文书
python自然语言处理之字典树知识总结
2021/04/25 Python
vue组件的路由高亮问题解决方法
2021/05/11 Vue.js
MySQL子查询中order by不生效问题的解决方法
2021/08/02 MySQL
《王者天下》第4季首话新剧照 4月9日正式开播
2022/04/07 日漫
Nginx跨域问题解析与解决
2022/08/05 Servers