解析如何在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
两个开源的Php输出Excel文件类
Feb 08 PHP
php中修改浏览器的User-Agent来伪装你的浏览器和操作系统
Jul 29 PHP
PHP 使用memcached简单示例分享
Mar 05 PHP
php usort 使用用户自定义的比较函数对二维数组中的值进行排序
May 02 PHP
PHP实现的链式队列结构示例
Sep 15 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
Feb 10 PHP
在Laravel5.6中使用Swoole的协程数据库查询
Jun 15 PHP
laravel 关联关系遍历数组的例子
Oct 10 PHP
Laravel 修改验证异常的响应格式实例代码详解
May 25 PHP
PHP字符串和十六进制如何实现互相转换
Jul 16 PHP
php 文件上传至OSS及删除远程阿里云OSS文件
Jul 04 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
PHP得到某段时间区间的时间戳 php定时任务
2012/04/12 PHP
XML+XSL 与 HTML 两种方案的结合
2007/04/22 Javascript
kmock javascript 单元测试代码
2011/02/06 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
2015/12/25 Javascript
javascript自动切换焦点控制效果完整实例
2016/02/02 Javascript
javascript html5移动端轻松实现文件上传
2020/03/27 Javascript
jQuery绑定事件-多种实现方式总结
2016/05/09 Javascript
Bootstrap Table使用方法详解
2016/08/01 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
前端框架学习总结之Angular、React与Vue的比较详解
2017/03/14 Javascript
微信小程序实现折叠面板
2018/01/31 Javascript
微信小程序仿微信运动步数排行(交互)
2018/07/13 Javascript
vue踩坑记-在项目中安装依赖模块npm install报错
2019/04/02 Javascript
javascript 使用sleep函数的常见方法详解
2020/04/26 Javascript
js实现Element中input组件的部分功能并封装成组件(实例代码)
2021/03/02 Javascript
[02:57]DOTA2英雄基础教程 风行者
2014/01/16 DOTA
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
Python模块学习 filecmp 文件比较
2012/08/27 Python
python中反射用法实例
2015/03/27 Python
Python MD5加密实例详解
2017/08/02 Python
python提取log文件内容并画出图表
2019/07/08 Python
python3字符串操作总结
2019/07/24 Python
python字典的setdefault的巧妙用法
2019/08/07 Python
Eyeko美国:屡获殊荣的睫毛膏、眼线笔和眉妆
2018/07/05 全球购物
介绍一下linux的文件系统
2012/03/20 面试题
2014乡镇“三八”国际劳动妇女节活动总结
2014/03/01 职场文书
优秀公益广告词大全
2014/03/19 职场文书
2014年双拥工作总结
2014/11/21 职场文书
2015年幼儿园中班下学期工作总结
2015/05/22 职场文书
电影建国大业观后感
2015/06/01 职场文书
军训新闻稿范文
2015/07/17 职场文书
中小学教师继续教育心得体会
2016/01/19 职场文书
党员心得体会范文2016
2016/01/23 职场文书
2016年度基层党建工作公开承诺书
2016/03/25 职场文书
什么是检讨书?检讨书的格式及范文
2019/11/05 职场文书
Java设计模式中的命令模式
2022/04/28 Java/Android