解析如何在PHP下载文件名中解决乱码的问题


Posted in PHP onJune 20, 2013

通过把Content-Type设置为application/octet-stream,可以把动态生成的内容当作文件来下载,相信这个大家都会。那么用Content-Disposition设置下载的文件名,这个也有不少人知道吧。基本上,下载程序都是这么写的:

$filename = "document.txt";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
print "Hello!";
?>

但是,如果$filename是UTF-8编码的,有些浏览器就无法正常处理了。比如把上面那个程序稍稍改一下:
$filename = "中文 文件名.txt";
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
print "Hello!";
?>

输出的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=""
FF3
attachment; filename="UTF-8文件名"
attachment; filename*="utf8''"
O9
attachment; filename="UTF-8文件名"
Safari3(Win)
貌似不支持?上述方法都不行
这样看来,程序必须得这样写才能支持所有主流浏览器:
$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
Apache2 httpd.conf 中文版
Dec 06 PHP
PHP扩展编写点滴 技巧收集
Mar 09 PHP
使用php shell命令合并图片的代码
Jun 23 PHP
php中++i 与 i++ 的区别
Aug 08 PHP
android上传图片到PHP的过程详解
Aug 03 PHP
基础的WordPress插件制作教程
Nov 24 PHP
php文档工具PHP Documentor安装与使用方法
Jan 25 PHP
thinkPHP5框架自定义验证器实现方法分析
Jun 11 PHP
php闭包中使用use声明变量的作用域实例分析
Aug 09 PHP
PHP中__set()实例用法和基础讲解
Jul 23 PHP
Yii2框架中一些折磨人的坑
Dec 15 PHP
解析smarty 截取字符串函数 truncate的用法介绍
Jun 20 #PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
Jun 20 #PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
Jun 20 #PHP
解析php利用正则表达式解决采集内容排版的问题
Jun 20 #PHP
解析使用substr截取UTF-8中文字符串出现乱码的问题
Jun 20 #PHP
用Json实现PHP与JavaScript间数据交换的方法详解
Jun 20 #PHP
使用php 获取时间今天明天昨天时间戳的详解
Jun 20 #PHP
You might like
BBS(php & mysql)完整版(八)
2006/10/09 PHP
Yii结合CKEditor实现图片上传功能
2014/06/13 PHP
ThinkPHP3.1.3版本新特性概述
2014/06/19 PHP
php常量详细解析
2015/10/27 PHP
PHP实现的构造sql语句类实例
2016/02/03 PHP
PHP PDOStatement::fetchColumn讲解
2019/01/31 PHP
用js实现多域名不同文件的调用方法
2007/01/12 Javascript
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
jQuery 前的按键判断代码
2010/03/19 Javascript
JavaScript的setAttribute兼容性问题解决方法
2013/11/11 Javascript
分享一则javascript 调试技巧
2015/01/02 Javascript
jQuery+AJAX实现无刷新下拉加载更多
2015/07/03 Javascript
浅谈EasyUI常用控件的禁用方法
2016/11/09 Javascript
详解Angular的双向数据绑定(MV-VM)
2016/12/26 Javascript
canvas快速绘制圆形、三角形、矩形、多边形方法介绍
2016/12/29 Javascript
使用JQ完成表格隔行换色的简单实例
2017/08/25 Javascript
javascript运行机制之执行顺序理解
2020/08/03 Javascript
[03:02]2014DOTA2西雅图邀请赛 让队员自己告诉你DK NAVI备战情况
2014/07/08 DOTA
在GitHub Pages上使用Pelican搭建博客的教程
2015/04/25 Python
解析Python中while true的使用
2015/10/13 Python
python xml.etree.ElementTree遍历xml所有节点实例详解
2016/12/04 Python
wtfPython—Python中一组有趣微妙的代码【收藏】
2018/08/31 Python
Python递归及尾递归优化操作实例分析
2020/02/01 Python
Python Flask异步发送邮件实现方法解析
2020/08/01 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
旅游管理专业个人求职信范文
2013/12/24 职场文书
工程师岗位职责规定
2014/02/26 职场文书
自我鉴定书
2014/03/24 职场文书
担保书范本
2015/01/20 职场文书
销售会议开幕词
2015/01/28 职场文书
活着观后感
2015/06/03 职场文书
2016校本研修培训心得体会
2016/01/08 职场文书
JavaScript实现简单图片切换
2021/04/29 Javascript
Mysql排序的特性详情
2021/11/01 MySQL
《勇者辞职不干了》ED主题曲无字幕动画MV公开
2022/04/13 日漫
table设置超出部分隐藏,鼠标移上去显示全部内容的方法
2022/12/24 HTML / CSS