PHP使用header下载时文件名中文乱码解决
2014-03-31 01:41
PHP
header
下载
中文乱码
摘要:用 PHP header 做文件下载时,中文文件名在 IE 和 Firefox 里老是乱码,分享一下按 RFC2231 规范处理不同浏览器兼容的方案。
一般情况下, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件。 但是, 这样做, 就没办法做一些统计, 权限检查等的工作。于是, 很多时候, 我们采用让PHP来做转发, 为用户提供文件下载。
$file = "/tmp/english.tar.gz";
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($file) . '"');
header("Content-Length: ". filesize($file));
readfile($file);
但是这个有一个问题,就是如果文件是中文名的话,有的用户可能下载后的文件名是乱码。 按照RFC2231的定义, 多语言编码的Content-Disposition应该这么定义: 1.filename后面的等号之前要加 * 2.filename的值用单引号分成三段,分别是字符集(utf8)、语言(空)和rawurlencode过的文件名 3.最好加上双引号,否则文件名中空格后面的部分在Firefox中显示不出来
$file = "/tmp/中文名.tar.gz";
$filename = basename($file);
header("Content-type: application/octet-stream");
//处理中文文件名
$ua = $_SERVER["HTTP_USER_AGENT"];
$encoded_filename = rawurlencode($filename);
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 . '"');
}
header("Content-Length: ". filesize($file));
readfile($file);
我在IE11下测试后,发现IE的版本显示已经不是原来的MSIE这样的格式了,如MSIE 9.0。IE11的是这样的:rv:11.0。所以你需要对上面的代码中第一个if条件做简单的修改,如下。
if (preg_match("/MSIE/", $ua) or preg_match("/rv:/", $ua))