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 相关文章推荐
不用数据库的多用户文件自由上传投票系统(2)
Oct 09 PHP
用PHP读取和编写XML DOM的实现代码
Feb 03 PHP
php模拟socket一次连接,多次发送数据的实现代码
Jul 26 PHP
关于PHP的相似度计算函数:levenshtein的使用介绍
Apr 15 PHP
PHP版QQ互联OAuth示例代码分享
Jul 05 PHP
PHP使用CURL模拟登录的方法
Jul 08 PHP
详谈PHP编码转换问题
Jul 28 PHP
WordPress的文章自动添加关键词及关键词的SEO优化
Mar 01 PHP
PHP的Yii框架中使用数据库的配置和SQL操作实例教程
Mar 17 PHP
php实现xml转换数组的方法示例
Feb 03 PHP
php反射学习之依赖注入示例
Jun 14 PHP
零基础php编程好学吗
Oct 11 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中使用Oracle数据库(5)
2006/10/09 PHP
如何从一个php文件向另一个地址post数据,不用表单和隐藏的变量的
2007/03/06 PHP
深入php中var_dump方法的使用详解
2013/06/24 PHP
php图像处理类实例
2015/07/28 PHP
详解PHP中的Traits
2015/07/29 PHP
PHP实现生成带背景的图形验证码功能
2016/10/03 PHP
PHP使用curl制作简易百度搜索
2016/11/03 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
让iframe子窗体取父窗体地址栏参数(querystring)
2009/10/13 Javascript
Javascript 解疑
2009/11/11 Javascript
深入理解JavaScript系列(11) 执行上下文(Execution Contexts)
2012/01/15 Javascript
js判断浏览器类型为ie6时不执行
2014/06/15 Javascript
在NodeJS中启用ECMAScript 6小结(windos以及Linux)
2014/07/15 NodeJs
jQuery实现返回顶部功能适合不支持js的浏览器
2014/08/19 Javascript
浅谈Sizzle的“编译原理”
2015/04/14 Javascript
配置Grunt的Task时通配符支持和动态生成文件名问题
2015/09/06 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
2016/06/01 Javascript
js鼠标移动时禁止选中文字
2017/02/19 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
bootstrap常用组件之头部导航实现代码
2017/04/20 Javascript
快速将Vue项目升级到webpack3的方法步骤
2017/09/14 Javascript
vue filters的使用详解
2018/06/11 Javascript
Python抽象类的新写法
2015/06/18 Python
使用python实现生成用户信息
2017/03/20 Python
Python cookbook(数据结构与算法)从序列中移除重复项且保持元素间顺序不变的方法
2018/03/13 Python
python Selenium 库的使用技巧
2020/10/16 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
2021/02/25 Python
英国绿色商店:Natural Collection
2019/05/03 全球购物
诉讼代理人授权委托书
2014/04/08 职场文书
项目建议书模板
2014/05/12 职场文书
大气污染防治方案
2014/05/19 职场文书
庆祝儿童节标语
2014/10/09 职场文书
异地恋情人节寄语
2015/02/28 职场文书
《圆明园的毁灭》教学反思
2016/02/16 职场文书
mysql在项目中怎么选事务隔离级别
2021/05/25 MySQL
python数字图像处理之图像的批量处理
2022/06/28 Python