当前位置: 首页 > 图文教程 > 网络编程 > PHP > PHP下载文件名乱码问题详解

PHP
php 多线程上下文中安全写文件实现代码
PHP类的使用 实例代码讲解
用php实现让页面只能被百度gogole蜘蛛访问的方法
php 学习笔记
PHP编程过程中需要了解的this,self,parent的区别
php 操作excel文件的方法小结
使用PHP获取网络文件的实现代码
PHP 巧用数组降低程序的时间复杂度
php下将XML转换为数组
php 文件上传代码(限制jpg文件)
php 无极分类(递归)实现代码
PHP 采集获取指定网址的内容
PHP 将图片按创建时间进行分类存储的实现代码
PHP 存储文本换行实现方法
PHP 批量更新网页内容实现代码
用PHP查询搜索引擎排名位置的代码
用php实现的获取网页中的图片并保存到本地的代码
php实现首页链接查询 友情链接检查的代码
处理php自动反斜杠的函数代码
php实现的遍历文件夹下所有文件,编辑删除

PHP下载文件名乱码问题详解


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 185 ::
收藏到网摘: n/a

通过把Content-Type设置为application/octet-stream,可以把动态生成的内容当作文件来下载,相信这个大家都会。那么用Content-Disposition设置下载的文件名,这个也有不少人知道吧。基本上,下载程序都是这么写的:

header('Content-Disposition: attachment; filename=' . $filename);print "Hello!";?> 

这样用浏览器打开之后,就可以下载document.txt。

但是,如果$filename是UTF-8编码的,有些浏览器就无法正常处理了。比如把上面那个程序稍稍改一下:

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=""

FF3 attachment; filename="UTF-8文件名"

attachment; filename*="utf8''"

O9 attachment; filename="UTF-8文件名"

Safari3(Win) 貌似不支持?上述方法都不行

这样看来,程序必须得这样写才能支持所有主流浏览器:

以下为引用的内容:

$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';?>