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文件的实现方法
Mar 19 PHP
php中$this-&amp;gt;含义分析
Nov 29 PHP
PHP获取文件后缀名的三个函数
Oct 15 PHP
php创建无限级树型菜单
Nov 05 PHP
php实现可运算的验证码
Nov 10 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
Dec 24 PHP
PHP实现获取并生成数据库字典的方法
May 04 PHP
PHP页面输出搜索后跳转下一页的处理方法
Sep 30 PHP
PHP CURL post数据报错 failed creating formpost data
Oct 16 PHP
PHP实现UTF8二进制及明文字符串的转化功能示例
Nov 20 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
May 11 PHP
Yii2框架加载css和js文件的方法分析
May 25 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 的几个配置文件函数
2006/12/21 PHP
php递归列出所有文件和目录的代码
2008/09/10 PHP
PHP中对各种加密算法、Hash算法的速度测试对比代码
2014/07/08 PHP
PHP文字转图片功能原理与实现方法分析
2017/08/31 PHP
php生成word并下载代码实例
2019/03/15 PHP
JS 操作符整理[推荐收藏]
2011/11/15 Javascript
基于jquery自己写tab滑动门(通用版)
2012/10/30 Javascript
如何获取select下拉框的值(option没有及有value属性)
2013/11/08 Javascript
D3.js实现饼状图的方法详解
2016/09/21 Javascript
Bootstrap基本插件学习笔记之按钮(21)
2016/12/08 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
2017/03/06 Javascript
angular-ngSanitize模块-$sanitize服务详解
2017/06/13 Javascript
微信小程序入门之广告条实现方法示例
2018/12/05 Javascript
详解JavaScript 高阶函数
2020/09/14 Javascript
python赋值操作方法分享
2013/03/23 Python
对于Python的Django框架部署的一些建议
2015/04/09 Python
Python内存管理方式和垃圾回收算法解析
2017/11/11 Python
Python 装饰器实现DRY(不重复代码)原则
2018/03/05 Python
Python判断两个list是否是父子集关系的实例
2018/05/04 Python
如何优雅地改进Django中的模板碎片缓存详解
2018/07/04 Python
Python找出微信上删除你好友的人脚本写法
2018/11/01 Python
python自动发送测试报告邮件功能的实现
2019/01/22 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
python xlwt如何设置单元格的自定义背景颜色
2019/09/03 Python
python实现字符串和数字拼接
2020/03/02 Python
复古服装:RetroStage
2019/05/10 全球购物
加拿大在线隐形眼镜和眼镜店:VisionPros
2019/10/06 全球购物
系统管理员的职责包括那些?管理的对象是什么?
2016/09/20 面试题
数学国培研修感言
2014/02/13 职场文书
家长会主持词
2014/03/26 职场文书
房屋认购协议书
2015/01/29 职场文书
有关水浒传的读书笔记
2015/06/25 职场文书
Python pygame实现中国象棋单机版源码
2021/06/20 Python
剑指Offer之Java算法习题精讲二叉树的构造和遍历
2022/03/21 Java/Android
SQL Server 中的事务介绍
2022/05/20 SQL Server