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 array_multisort() 函数的深入解析
Jun 20 PHP
深入extjs与php参数交互的详解
Jun 25 PHP
php文件上传的例子及参数详解
Dec 12 PHP
PHP中new static()与new self()的区别异同分析
Aug 22 PHP
PHP扩展模块memcached长连接使用方法分析
Dec 24 PHP
PHP传参之传值与传址的区别
Apr 24 PHP
PHP附件下载中文名称乱码的解决方法
Dec 17 PHP
thinkphp分页实现效果
Oct 13 PHP
Android AsyncTack 异步任务实例详解
Nov 02 PHP
php封装的验证码类分享
Feb 26 PHP
PHP实现将base64编码字符串转换成图片示例
Jun 22 PHP
详解Laravel服务容器的绑定与解析
Nov 05 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
Yii多表联合查询操作详解
2016/06/02 PHP
php中namespace及use用法分析
2016/12/06 PHP
图片格式的JavaScript和CSS速查手册
2007/08/20 Javascript
使用jquery插件实现图片延迟加载技术详细说明
2011/03/12 Javascript
关于js获取radio和select的属性并控制的代码
2011/05/12 Javascript
网页编辑器ckeditor和ckfinder配置步骤分享
2012/05/24 Javascript
文本框回车提交与禁止提交示例
2013/09/27 Javascript
基于javascript实现的搜索时自动提示功能
2014/12/26 Javascript
javascript操作符&quot;!~&quot;详解
2015/02/10 Javascript
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
jQuery实用技巧必备(下)
2015/11/03 Javascript
基于jquery实现瀑布流布局
2020/06/28 Javascript
不同js异步函数同步的实现方法
2016/05/28 Javascript
JS中对数组元素进行增删改移的方法总结
2016/12/15 Javascript
React操作真实DOM实现动态吸底部的示例
2017/10/23 Javascript
nodejs中安装ghost出错的原因及解决方法
2017/10/23 NodeJs
Vue.js图片预览插件使用详解
2018/08/27 Javascript
微信小程序使用map组件实现路线规划功能示例
2019/01/22 Javascript
vue vant中picker组件的使用
2020/11/03 Javascript
python中pygame模块用法实例
2014/10/09 Python
Python获取网页上图片下载地址的方法
2015/03/11 Python
python操作excel文件并输出txt文件的实例
2018/07/10 Python
详解利用Python scipy.signal.filtfilt() 实现信号滤波
2019/06/05 Python
Anaconda和ipython环境适配的实现
2020/04/22 Python
英国女鞋购物网站:Moda in Pelle
2019/02/18 全球购物
简述数组与指针的区别
2014/01/02 面试题
医学院毕业生自荐信
2013/11/08 职场文书
工地标语大全
2014/06/18 职场文书
2014年人民警察入党思想汇报
2014/10/12 职场文书
优秀班主任先进事迹材料
2014/12/16 职场文书
《穷人》教学反思
2016/02/19 职场文书
生鲜超市—未来中国最具有潜力零售业态
2019/08/02 职场文书
mysql联合索引的使用规则
2021/06/23 MySQL
Oracle 临时表空间SQL语句的实现
2021/09/25 Oracle
Python+腾讯云服务器实现每日自动健康打卡
2021/12/06 Python
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技