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 相关文章推荐
对javascript和select部件的结合运用
Oct 09 PHP
解决MySQL中文输出变成问号的问题
Jun 05 PHP
检查url链接是否已经有参数的php代码 添加 ? 或 &amp;
Feb 09 PHP
php无限分类且支持输出树状图的详细介绍
Jun 19 PHP
web server使用php生成web页面的三种方法总结
Oct 28 PHP
Drupal简体中文语言包安装教程
Sep 27 PHP
关于URL最大长度限制的相关资料查证
Dec 23 PHP
php中文验证码实现方法
Jun 18 PHP
PHP curl使用实例
Jul 02 PHP
php自动加载方式集合
Apr 04 PHP
PHP魔术方法之__call与__callStatic使用方法
Jul 23 PHP
Django中的cookie与session操作实例代码
Aug 17 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学习之PHP变量
2006/10/09 PHP
mysql+php分页类(已测)
2008/03/31 PHP
ThinkPHP使用心得分享-分页类Page的用法
2014/05/15 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
2016/07/14 PHP
PHP使用new StdClass()创建空对象的方法分析
2017/06/06 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
javascript编程起步(第三课)
2007/02/27 Javascript
使用Js让Html中特殊字符不被转义
2013/11/05 Javascript
对 jQuery 中 data 方法的误解分析
2014/06/18 Javascript
JS 排序输出实现table行号自增前端动态生成的tr
2014/08/13 Javascript
微信小程序 获取设备信息 API实例详解
2016/10/02 Javascript
详解js数组的完全随机排列算法
2016/12/16 Javascript
JS中如何实现点击a标签返回页面顶部的问题
2017/01/19 Javascript
jQuery基于正则表达式的表单验证功能示例
2017/01/21 Javascript
javascript中apply/call和bind的使用
2017/02/15 Javascript
JavaScript实现删除数组重复元素的5种常用高效算法总结
2018/01/18 Javascript
vue头部导航动态点击处理方法
2018/11/02 Javascript
JavaScript箭头函数中的this详解
2019/06/19 Javascript
Vue中watch、computed、updated三者的区别及用法
2020/07/27 Javascript
vue实现公共方法抽离
2020/07/31 Javascript
Python设计模式中单例模式的实现及在Tornado中的应用
2016/03/02 Python
Window10+Python3.5安装opencv的教程推荐
2018/04/02 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
2018/07/27 Python
从0开始的Python学习016异常
2019/04/08 Python
使用Python的OpenCV模块识别滑动验证码的缺口(推荐)
2019/05/10 Python
IE9对HTML5中部分属性不支持的原因分析
2014/10/15 HTML / CSS
Html5跳转到APP指定页面的实现
2020/01/14 HTML / CSS
html5使用window.postMessage进行跨域实现数据交互的一次实战
2021/02/24 HTML / CSS
送给程序员的20个Java集合面试问题
2014/08/06 面试题
读书活动总结
2014/04/28 职场文书
创意婚礼策划方案
2014/05/18 职场文书
舞蹈教育学专业自荐信
2014/06/15 职场文书
幼儿园推普周活动总结
2015/05/07 职场文书
安全温馨提示语大全
2015/07/14 职场文书
学校运动会简讯
2015/07/20 职场文书
pytorch损失反向传播后梯度为none的问题
2021/05/12 Python