php

位置:IT落伍者 >> php >> 浏览文章

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


发布日期:2020年11月23日
 
PHP下载文件名乱码问题详解

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

header(ContentDisposition: attachment; filename= $filename);print Hello!;?>

这样用浏览器打开之后就可以下载documenttxt

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

header(ContentDisposition: attachment; filename= $filename);print Hello!;?>

把程序保存成UTF编码再访问IE下载的文件名就会乱码 FF下下载的文件名就只有中文两个字Opera 下一切正常

输出的header实际上是这样子

ContentDisposition: attachment; filename=中文 文件名txt

其实按照RFC的定义多语言编码的ContentDisposition应该这么定义

ContentDisposition: attachment; filename*=utf%E%B%AD%E%%%%E%%%E%BB%B%E%%Dtxt

filename后面的等号之前要加 * filename的值用单引号分成三段分别是字符集(utf)语言(空)和urlencode过的文件名 最好加上双引号否则文件名中空格后面的部分在Firefox中显示不出来 注意urlencode的结果与php的urlencode函数结果不太相同php的urlencode会把空格替换成+而这里需要替换成%

经过试验发现几种主流浏览器的支持情况如下

IE attachment; filename=

FF attachment; filename=UTF文件名

attachment; filename*=utf

O attachment; filename=UTF文件名

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

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

$encoded_filename = urlencode($filename);$encoded_filename = str_replace(+ %

$encoded_filename);header(ContentType: application/octetstream);

if (preg_match(/MSIE/ $ua)) { header(ContentDisposition: attachment;

filename= $encoded_filename );} else if (preg_match(/Firefox/ $ua))

{ header(ContentDisposition: attachment; filename*=utf\\ $filename );}

else { header(ContentDisposition: attachment; filename= $filename );}print ABC;?>

上一篇:PHP网络开发详解:远程文件包含漏洞

下一篇:PHPer为什么被认为是草根?[2]