[完]PHP文件下载 下载GET值中含有中文字符的文件,保存中文文件名,文件不能打开,遇到的编码问题
来源:互联网 发布:中英文即时口译软件 编辑:程序博客网 时间:2024/05/20 04:49
编码问题:
使用Windows Server 2008英文版作为服务器,文件系统中文件名存储的编码与Windows“当前系统区域设置”相关。(例如:中文默认为GB2312,俄文为西里尔文Windows[windows-1251])
文本编辑器采用的编码。
- Windows Notepad默认的文字编码是ANSI。
- Notepad++,可以通过“格式 | 转为UTF-8无BOM编码格式”,将编码转化为UTF-8无BOM格式。采用服务器的语言版本不一样时,有所差别,英文Windows 2008服务器时,PHP文件格式设为“UTF-8编码”,这样下载的文件才能正确打开。
打开下载的文件出现问题。
- 使用中文Windows 2008服务器时,PHP文件编码格式设为“UTF-8无BOM编码”
- 使用英文Windows 2008 服务器时,PHP文件格式设为“UTF-8编码”
Web服务器采用Apache。默认编码为UTF-8,GET值的编码也是UTF-8。
# 设置PHP页采用的编码,如果使用Windows自带的Notepad编码,且不在首行设置编码,那么默认采用的是ANSI编码header("Content-Type: text/html; charset=UTF-8");$getFile = $_GET['f'];echo 'GET filename: ' . $getFile . '<br/>';# 将get中获取的filename转换成os认识的filename,这样file_exists()才认,才能下载相应文件。$osFile = iconv('utf-8','GB2312', $getFile);echo 'OS filename: ' . $osFile . '<br/>';if( file_exists($osFile) ) { echo 'exist';} else { echo 'not exist';}
http://192.168.1.102/test.php?f=中文.txt
的执行结果
GET filename: 中文.txtOS filename: ����.txtexist
如果去掉上述代码的header("Content-Type: text/html; charset=UTF-8");
,采用Notepad,但是另存为编码“UTF-8”的文件,执行结果和上面一样。如果采用Notepad默认ANSI编码,执行结果则是:
GET filename: 涓枃.txtOS filename: 中文.txtexist
- basename($pFileName):对含有中文字符的文件名无效,解决方法:
end(explode('/',$pFileName));
- file_exists($fileName):对解析中文文件名有问题。主要是编码问题,只有将文件名转换为Windows服务器“当前系统区域设置”中语言采用的默认语言编码才行。
- IE浏览器中,即使页面默认选择是UTF-8,链接中中文字符串依然使用GB2312编码,看下面代码在不同浏览器中执行var_dump()函数的结果
header("Content-Type: text/html; charset=UTF-8");$getFile = $_GET['f'];echo 'var_dump getFile: ';var_dump($getFile);echo '<br/>';
PHP页面代码如上,使用http://192.168.1.102/test1.php?f=中文
,访问页面。在不同浏览器中结果。
var_dump getFile: string(6) "中文"
var_dump getFile: string(4) "����"
使用一种为每个文件创建一个数字目录,去目录下搜索文件并下载,绕过GET传中文文件名。规避了各种编码问题。但是如果不注意Windows中“当前系统区域设置”的话,由中文服务器换到英文服务器上,会出现问题,需要将“当前系统区域设置”设置到“中文(简体,中国)”。
程序代码
下面代码可在360,Chrome和Firefox正常使用,但在IE下存在问题。
<?phpheader("Content-Type: text/html; charset=UTF-8");$getFile = $_GET['f'];# 将浏览器传入的UTF-8编码的文件名,转换成Windows服务器认的GB2312编码,然后才能下载相关文件$osFile = iconv('UTF-8','GB2312', $getFile);downfile('./d/'.$osFile);function downfile($osFile) { if(file_exists($osFile)) { # basename() 消除文件路径,只保留文件名,对于中文出现问题,应该就是编码问题, # 处理好编码问题,应该可以使用basename()函数 # $saveName = basename($osFile); $saveName = end(explode('/', $osFile)); # 将Windows服务器认的GB2312编码,转换成浏览器认的UTF-8编码 $saveName = iconv('GB2312', 'UTF-8', $saveName); header("Content-Type: application/octet-stream"); header("Accept-Ranges: bytes"); # 计算文件大小,使用Windows服务器认的GB2312编码 header("Accept-Length: ".filesize($osFile)); # 在浏览器端保存文件,使用浏览器认的UTF-8编码 header("Content-Disposition: attachment; filename=\"{$saveName}\""); # 读取文件,使用Windows服务器认的GB2312编码 readfile($osFile); } else { echo "The file is not exist!"; }}?>
下面代码可在IE,Chrome和Firefox正常使用,但在360下存在问题。
<?phpheader("Content-Type: text/html; charset=UTF-8");$getFile = $_GET['f'];# 将浏览器传入的UTF-8编码的文件名,转换成Windows服务器认的GB2312编码,然后才能下载相关文件$osFile = iconv('UTF-8','GB2312', $getFile);$osPathFile = './d/'.$osFile;$browser = $_SERVER['HTTP_USER_AGENT'];# 如果是IE的话if( strpos($browser, "Trident") > -1 || strpos($browser, "MSIE") > -1) { # 获取保存文件名 $saveFile = $getFile; downFileIE( $osPathFile, $saveFile); # mb_convert_encoding与iconv功能类似,但是它是将第一个参数的原来编码放在最后一个参数位置,需要转变的编码是第二个参数} else { downFile($osPathFile);}function downFile($osPathFile) { if(file_exists($osPathFile)) { # basename() 消除文件路径,只保留文件名,对于中文出现问题,应该就是编码问题, # 处理好编码问题,应该可以使用basename()函数 # $saveName = basename($osFile); $saveName = end(explode('/', $osPathFile)); # 将Windows服务器认的GB2312编码,转换成浏览器认的UTF-8编码 $saveName = iconv('GB2312', 'UTF-8', $saveName); header("Content-Type: application/octet-stream"); header("Accept-Ranges: bytes"); # 计算文件大小,使用Windows服务器认的GB2312编码 header("Accept-Length: ".filesize($osPathFile)); # 在浏览器端保存文件,使用浏览器认的UTF-8编码 header("Content-Disposition: attachment; filename=\"{$saveName}\""); # 读取文件,使用Windows服务器认的GB2312编码 readfile( $osPathFile); } else { echo "The file is not exist!"; }}function downFileIE($osPathFile, $saveFile) { if(file_exists($osPathFile)) { header("Content-Type: application/octet-stream"); header("Accept-Ranges: bytes"); # 计算文件大小,使用Windows服务器认的GB2312编码 header("Accept-Length: ".filesize($osFile)); # 在浏览器端保存文件,使用浏览器认的UTF-8编码 header("Content-Disposition: attachment; filename=\"{$saveFile}\""); # 读取文件,使用Windows服务器认的GB2312编码 readfile('./d/'.$saveFile); } else { echo "The file is not exist!"; }}?>
如果服务器保存的是其他国家语言的文本,可以统一将程序中GB2312编码,转换相应国家的语言编码,注意在Windows系统设置中,将“当前系统区域设置”设置成相应的国家和语言。
- [完]PHP文件下载 下载GET值中含有中文字符的文件,保存中文文件名,文件不能打开,遇到的编码问题
- php中fopen不能创建中文文件名文件的问题
- 解决FlashFXP5 不能下载中文文件名文件的问题(显示文件名中文正常下载文件名是乱码)
- 文件下载中文文件名问题
- struts2 实现中文文件名的文件下载
- 文件名含中文的JavaWeb文件下载
- java文件下载的中文文件名乱码问题的解决
- struts2文件下载的时候,处理中文文件名的问题
- 关于android在TOMCAT服务器下载文件名带中文的文件的编码问题
- http下载文件,中文文件名在firefox下编码问题
- 终于解决了中文文件名文件下载的问题
- 打包下载文件 中文文件名乱码问题的解决
- 下载文件默认文件名中文乱码问题的解决
- 下载文件时的中文文件名问题(asp.net)
- 关于在浏览器中输入含有中文的下载的文件的问题引发的问题
- php 文件下载 处理中文文件名
- 中文文件下载文件名乱码问题
- Struts2 文件下载中文文件名乱码问题
- Python的re
- Android 中Java 和C/C++的相互调用方法
- 高性能流媒体服务器-nebula之数据结构(1)--hash table介绍
- sublime注册码
- linux内存源码分析 - 伙伴系统(初始化和申请页框)
- [完]PHP文件下载 下载GET值中含有中文字符的文件,保存中文文件名,文件不能打开,遇到的编码问题
- 双目视觉
- 使用ASP.Net WebAPI构建REST服务(一)——简单的示例
- Docker源码分析(一):Docker架构
- ConstraintLayout约束布局的概念与使用
- 初学Hadoop之图解MapReduce与WordCount示例分析
- openstack调试数据库语句
- hdu2602 Bone Collector 01背包教学题
- Fiddler教程