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
drupal 代码实现URL重写
May 04 PHP
基于Zookeeper的使用详解
May 02 PHP
使用PHP编写的SVN类
Jul 18 PHP
php微信公众开发之获取周边酒店信息的方法
Dec 22 PHP
php实现字符串反转输出的方法
Mar 14 PHP
php实现比较两个字符串日期大小的方法
May 12 PHP
PHP中你应该知道的require()文件包含的正确用法
Jun 12 PHP
PHP简单读取PDF页数的实现方法
Jul 21 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
Mar 31 PHP
详解PHP的抽象类和抽象方法以及接口总结
Mar 15 PHP
php基于协程实现异步的方法分析
Jul 17 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 DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(五)
2014/06/23 PHP
php自动识别文字编码并转换为目标编码的方法
2015/08/08 PHP
4种PHP异步执行的常用方式
2015/12/24 PHP
Symfony2框架学习笔记之HTTP Cache用法详解
2016/03/18 PHP
thinkphp3.x自定义Action、Model及View的简单实现方法
2016/05/19 PHP
PHP编写文件多服务器同步程序
2016/07/02 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
比较详细的javascript对象的property和prototype是什么一种关系
2007/08/06 Javascript
cloudgamer出品ImageZoom 图片放大效果
2010/04/01 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
2013/01/25 Javascript
js页面跳转的问题(跳转到父页面、最外层页面、本页面)
2013/08/14 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
Javascript学习笔记之函数篇(五) : 构造函数
2014/11/23 Javascript
微信开发 微信授权详解
2016/10/21 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
jquery仿京东商品放大浏览页面
2017/06/06 jQuery
Vue 表单控件绑定的实现示例
2017/08/11 Javascript
AngularJS基于MVC的复杂操作实例讲解
2017/12/31 Javascript
Vue js with语句原理及用法解析
2020/09/03 Javascript
[56:35]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第一局
2016/03/06 DOTA
pycharm 使用心得(二)设置字体大小
2014/06/05 Python
利用python爬取散文网的文章实例教程
2017/06/18 Python
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
2017/08/08 Python
使用python批量读取word文档并整理关键信息到excel表格的实例
2018/11/07 Python
python实现求特征选择的信息增益
2018/12/18 Python
200行python代码实现2048游戏
2019/07/17 Python
Python list运算操作代码实例解析
2020/01/20 Python
Python定义函数实现累计求和操作
2020/05/03 Python
怎么快速自学python
2020/06/22 Python
利用HTML5实现使用按钮控制背景音乐开关
2015/09/21 HTML / CSS
英国时尚服饰电商:Boohoo
2017/10/12 全球购物
EQVVS官网:设计师男装和女装
2018/10/24 全球购物
外贸公司实习自我鉴定
2013/09/24 职场文书
采购员岗位职责
2015/02/03 职场文书
拔河比赛新闻稿
2015/07/17 职场文书