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出错界面
Oct 09 PHP
967 个函式
Oct 09 PHP
Breeze 文章管理系统 v1.0.0正式发布
Dec 14 PHP
利用curl抓取远程页面内容的示例代码
Jul 23 PHP
PHPMailer的主要功能特点和简单使用说明
Feb 17 PHP
php中http与https跨域共享session的解决方法
Dec 20 PHP
PHP将MySQL的查询结果转换为数组并用where拼接的示例
May 13 PHP
PHP简单实现DES加密解密的方法
Jul 12 PHP
PDO::commit讲解
Jan 27 PHP
PHP实现通过文本文件统计页面访问量功能示例
Feb 13 PHP
php和js实现根据子网掩码和ip计算子网功能示例
Nov 09 PHP
Laravel框架Eloquent ORM简介、模型建立及查询数据操作详解
Dec 04 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框架获取当前controlle和action对应id的方法
2014/12/03 PHP
制作个性化的WordPress登陆界面的实例教程
2016/05/21 PHP
Netbeans 8.2将支持PHP7 更精彩
2016/06/13 PHP
PDO::quote讲解
2019/01/29 PHP
PHP常用函数之base64图片上传功能详解
2019/10/21 PHP
JavaScript strike方法入门实例(给字符串加上删除线)
2014/10/17 Javascript
jQuery实现仿Alipay支付宝首页全屏焦点图切换特效
2015/05/04 Javascript
有关json_decode乱码及NULL的问题
2015/10/13 Javascript
javascript下拉列表菜单的实现方法
2015/11/18 Javascript
switch语句的妙用(必看篇)
2016/10/03 Javascript
移动端日期插件Mobiscroll.js使用详解
2016/12/19 Javascript
原生js实现图片放大缩小计时器效果
2017/01/20 Javascript
学习使用jQuery表单验证插件和日历插件
2017/02/13 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
2019/07/15 Javascript
Python socket实现简单聊天室
2018/04/01 Python
Django处理文件上传File Uploads的实例
2018/05/28 Python
Python3的高阶函数map,reduce,filter的示例详解
2019/07/23 Python
Python如何基于smtplib发不同格式的邮件
2019/12/30 Python
pytorch逐元素比较tensor大小实例
2020/01/03 Python
Tensorflow 模型转换 .pb convert to .lite实例
2020/02/12 Python
CSS3关于z-index不生效问题的解决
2020/02/19 HTML / CSS
HTML5地理定位实例
2014/10/15 HTML / CSS
谈一谈HTML5本地存储技术
2016/03/02 HTML / CSS
完美解决IE8下不兼容rgba()的问题
2017/03/31 HTML / CSS
html5实现移动端适配完美写法
2017/11/16 HTML / CSS
比利时网上药店: Drogisterij.net
2017/03/17 全球购物
英国钻石公司:British Diamond Company
2020/02/16 全球购物
大学生职业生涯规划范文
2013/12/31 职场文书
商务英语专业求职信范文
2014/01/28 职场文书
能源工程专业应届生求职信
2014/03/01 职场文书
国旗下的演讲稿
2014/05/08 职场文书
2014年学生会部门工作总结
2014/11/07 职场文书
律师催款函范文
2015/06/24 职场文书
python如何获取网络数据
2021/04/11 Python
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang
Redis实现一个账号只能登录一个设备
2022/04/19 Redis