PHP文件下载脚本含特殊字符文件名失效的修复方法
修复PHP下载脚本中含特殊字符的文件名问题
这个问题我碰到过好几次!核心原因是HTTP协议对Content-Disposition头里的filename参数有严格的字符限制,像星号这类特殊字符直接放进去会被浏览器当成无效内容,导致文件名解析失败。
解决思路
HTTP标准(RFC 5987)定义了专门的编码方式来处理含特殊字符的文件名,我们需要对文件名进行URL编码,同时通过filename*参数明确告知浏览器编码格式,这样既能兼容现代浏览器,也能照顾旧版本的兼容需求。
修改后的完整代码
<?php $path = 'myfile.mp3'; $name = '**filename.mp3'; // 对文件名进行URL编码,适配标准规范 $encodedFileName = rawurlencode($name); header('Content-Description: File Transfer'); header("Content-Type: audio/mp3"); header("Content-Transfer-Encoding: binary"); // 同时设置兼容旧浏览器的filename和标准的filename*参数 header("Content-Disposition: attachment; filename=\"".addslashes($name)."\"; filename*=UTF-8''".$encodedFileName); readfile($path); exit(); ?>
代码说明
rawurlencode()编码:把文件名里的特殊字符(比如*)转换成浏览器能识别的URL编码格式(星号会被转成%2A)。- 双参数设置:
filename=\"".addslashes($name)."\":针对不支持filename*的旧浏览器,用addslashes()转义文件名里可能存在的双引号,避免破坏HTTP头的格式。filename*=UTF-8''".$encodedFileName:遵循RFC 5987标准,明确告诉浏览器文件名是UTF-8编码的URL编码字符串,现代浏览器会优先解析这个参数,正确显示含特殊字符的文件名。
额外注意事项
- 确保你的PHP脚本文件本身是UTF-8编码,避免文件名出现编码乱码。
- 如果文件名包含中文等非ASCII字符,这个方案同样适用,不用额外处理编码转换(只要文件名本身是UTF-8格式)。
内容的提问来源于stack exchange,提问作者Wojciech Urbaniak
相关产品推荐
相关产品推荐

