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 相关文章推荐
WHOIS类的修改版
Oct 09 PHP
如何写php程序?
Dec 08 PHP
Phpbean路由转发的php代码
Jan 10 PHP
FCKeditor添加自定义按钮
Mar 27 PHP
PHP生成条形码大揭秘
Sep 24 PHP
注释PHP和html混合代码的小技巧(分享)
Nov 03 PHP
php遍历替换目录下文件指定内容的方法
Nov 10 PHP
php使用gd2绘制基本图形示例(直线、圆、正方形)
Feb 15 PHP
Laravel中批量赋值Mass-Assignment的真正含义详解
Sep 29 PHP
php-msf源码详解
Dec 25 PHP
php实现构建排除当前元素的乘积数组方法
Oct 06 PHP
详解no input file specified 三种解决方法
Nov 29 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防注入,表单提交值转义的实现详解
2013/06/10 PHP
thinkPHP分组后模板无法加载问题解决方法
2016/07/12 PHP
Yii遍历行下每列数据的方法
2016/10/17 PHP
thinkphp5框架API token身份验证功能示例
2019/05/21 PHP
Js 获取HTML DOM节点元素的方法小结
2009/04/24 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
jQuery 选择表格(table)里的行和列及改变简单样式
2012/12/15 Javascript
用json方式实现在 js 中建立一个map
2014/05/02 Javascript
nodejs批量修改文件编码格式
2015/01/22 NodeJs
jQuery异步上传文件插件ajaxFileUpload详细介绍
2015/05/19 Javascript
JavaScript程序中的流程控制语句用法总结
2016/05/23 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
2016/10/11 Javascript
JavaScript实现类似拉勾网的鼠标移入移出效果
2016/10/27 Javascript
jQuery 插件封装的方法
2016/11/16 Javascript
JavaScript的兼容性与调试技巧
2016/11/22 Javascript
无阻塞加载js,防止因js加载不了影响页面显示的问题
2016/12/18 Javascript
Node.JS使用Sequelize操作MySQL的示例代码
2017/10/09 Javascript
vue实现树形菜单效果
2018/03/19 Javascript
解决layer.prompt无效的问题
2019/09/24 Javascript
nodejs各种姿势断点调试的方法
2020/06/18 NodeJs
jQuery+ajax实现文件上传功能
2020/12/22 jQuery
理解生产者消费者模型及在Python编程中的运用实例
2016/06/26 Python
使用python画社交网络图实例代码
2019/07/10 Python
Python中的self用法详解
2019/08/06 Python
Django获取该数据的上一条和下一条方法
2019/08/12 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
Python进行特征提取的示例代码
2020/10/15 Python
html5+css3之动画在webapp中的应用
2014/11/21 HTML / CSS
swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
2013/03/30 面试题
优秀团员个人事迹材料
2014/01/29 职场文书
出纳员岗位职责风险
2014/03/06 职场文书
小学绿色学校申报材料
2014/08/23 职场文书
无犯罪记录证明范本
2014/09/15 职场文书
道德模范事迹材料
2014/12/20 职场文书
趣味运动会广播稿
2015/08/19 职场文书
mongodb的安装和开机自启动详细讲解
2021/08/02 MongoDB