php上传中文文件名乱码问题处理方案


Posted in PHP onFebruary 03, 2015

php上传文件是最最基础的一个技术点,但是深入进去也有不少问题需要解决,这不,上传中文文件后,文件名变成了乱码。

下面是问题代码,很简单:

1.问题代码

html部分:

 <html>

 <body>

 <form action="upload_file.php" method="post"

 enctype="multipart/form-data">

 <label for="file">Filename:</label>

 <input type="file" name="file" id="file" /> 

 <br />

 <input type="submit" name="submit" value="Submit" />

 </form>

 </body>

 </html>

php部分:
 

 <?php

 if ($_FILES["file"]["error"] > 0)

 {

     echo "Return Code: " . $_FILES["file"]["error"] . "<br />";

 }else

 {

     echo "Upload: " . $_FILES["file"]["name"] . "<br />";

     echo "Type: " . $_FILES["file"]["type"] . "<br />";

     echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";

     echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

     if (file_exists("upload/" . $_FILES["file"]["name"]))

     {

         echo $_FILES["file"]["name"] . " already exists. ";

     }

     else

     {

       move_uploaded_file($_FILES["file"]["tmp_name"],

       "upload/" . $_FILES["file"]["name"]);

     }

 }

上传了一个文件名为“测试数据.txt”的文件,oh ho,文件是传上去了,但是文件名为乱码。

2.初试

网上搜索一下解决方案,将

move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);

改成

move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . iconv("UTF-8","gbk",$_FILES["file"]["name"]));

结果发现iconv函数返回值为false。

查一下函数手册,发现第二个参数有特别的用法,简单翻译一下就是我可以在编码的后面追加//TRANSLIT 或 //IGNORE ,前者会将无法翻译的字符转成最接近的字符,后者就是直接忽略不能转化的字符。

php上传中文文件名乱码问题处理方案

试一下:

var_dump( iconv("UTF-8","gbk//TRANSLIT",$_FILES["file"]["name"]));

var_dump( iconv("UTF-8","gbk//IGNORE",$_FILES["file"]["name"]));

结果:

bool(false) string(4) ".txt"

也就是说中文都没法转化,甚至连接近的字符都没有,看来网上介绍的方法也并非万能。

3.网上介绍方法失败,再尝试

猜测一下,也许我的系统在创建中文文件的时候会乱码,于是我将代码改写了一下:

move_uploaded_file($_FILES["file"]["tmp_name"], "upload/测试数据.txt");

结果创建成功,没有乱码。。。也就是说不是系统问题。

想一下,我的php文件本身是utf8编码的,那么

move_uploaded_file($_FILES["file"]["tmp_name"],"upload/测试数据.txt");

这个语句肯定使用的是utf8编码,那么之前上传的文件名肯定就不是utf8编码了,那么以下的语句肯定是错误的,因为源字符串本身就不是utf8编码的:

iconv("UTF-8","gbk//TRANSLIT",$_FILES["file"]["name"]);

使用函数检查源字符串的编码:

$e=mb_detect_encoding($text, array(‘UTF-8', ‘GBK','gb2312'));

echo $e;

结果是CP936,也就是源字符串编码是GBK。

试一下

move_uploaded_file($_FILES["file"]["tmp_name"],"upload/" . iconv("gbk","UTF-8",$_FILES["file"]["name"]));

问题解决,不再乱码

4.另一种解决办法

实际上还有一种解决办法,就是在html文件的head标签中间加入

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

从而使编码保持统一,也就不需要再转码了

5.下面是结论

使用iconv函数可以解决上传中文文件名乱码的问题,实际上iconv能解决各种各样的由于编码不统一造成的乱码问题。
使用iconv函数请先检查源字符串的编码,除非你已经确定了源字符串的编码。
尽量保证所有的代码的编码一致,万不得已才使用iconv函数。
吐槽一下,尽量不使用中文文件名作为服务器上保存的文件名,请将文件名转化成自己的文件名(即使是英文文件名也请转化一下)。

PHP 相关文章推荐
用PHP实现的随机广告显示代码
Jun 14 PHP
用PHP实现维护文件代码
Jun 14 PHP
用php+javascript实现二级级联菜单的制作
May 06 PHP
MySql 按时间段查询数据方法(实例说明)
Nov 02 PHP
PHP 可阅读随机字符串代码
May 26 PHP
使用php shell命令合并图片的代码
Jun 23 PHP
深入解析php之apc
May 15 PHP
使用迭代器 遍历文件信息的详解
Jun 08 PHP
PHP中使用数组指针函数操作数组示例
Nov 19 PHP
微信利用PHP创建自定义菜单的方法
Aug 01 PHP
php数据序列化测试实例详解
Aug 12 PHP
thinkPHP5框架实现基于ajax的分页功能示例
Jun 12 PHP
php上传文件常见问题总结
Feb 03 #PHP
PHP、Python和Javascript的装饰器模式对比
Feb 03 #PHP
php对象在内存中的存在形式分析
Feb 03 #PHP
浅析THINKPHP的addAll支持的最大数据量
Feb 03 #PHP
php格式化金额函数分享
Feb 02 #PHP
php可应用于面包屑导航的迭代寻找家谱树实现方法
Feb 02 #PHP
php生成唯一的订单函数分享
Feb 02 #PHP
You might like
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
PHP初学者头疼问题总结
2006/07/08 PHP
PHP Memcached + APC + 文件缓存封装实现代码
2010/03/11 PHP
判断php数组是否为索引数组的实现方法
2013/06/13 PHP
php 从一个数组中随机的取出若干个不同的数实例
2016/12/31 PHP
PHP实现的简单AES加密解密算法实例
2017/05/29 PHP
PHP实现打包下载文件的方法示例
2017/10/07 PHP
javascript function、指针及内置对象
2009/02/19 Javascript
javascript检查表单数据是否改变的方法
2013/07/30 Javascript
jQuery+jRange实现滑动选取数值范围特效
2015/03/14 Javascript
写给小白的JavaScript引擎指南
2015/12/04 Javascript
使用jQuery制作Web页面遮罩层插件的实例教程
2016/05/26 Javascript
无循环 JavaScript(map、reduce、filter和find)
2017/04/08 Javascript
vue.js源代码core scedule.js学习笔记
2017/07/03 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
2017/08/29 Javascript
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
2017/09/19 Javascript
原生JS实现ajax与ajax的跨域请求实例
2017/12/01 Javascript
解决vue this.$forceUpdate() 处理页面刷新问题(v-for循环值刷新等)
2018/07/26 Javascript
JS实现把一个页面层数据传递到另一个页面的两种方式
2018/08/13 Javascript
vue组件系列之TagsInput详解
2020/05/14 Javascript
[16:14]教你分分钟做大人:米拉娜(HEROS)
2014/11/24 DOTA
对Python中range()函数和list的比较
2018/04/19 Python
python 识别图片中的文字信息方法
2018/05/10 Python
对python3 中方法各种参数和返回值详解
2018/12/15 Python
Python类super()及私有属性原理解析
2020/06/15 Python
H5页面适配iPhoneX(就是那么简单)
2019/12/02 HTML / CSS
html5视频常用API接口的实战示例
2020/03/20 HTML / CSS
中国跨境电子商务网站:NewFrog
2018/03/10 全球购物
关于圣诞节的广播稿
2014/01/26 职场文书
素质拓展感言
2014/01/29 职场文书
2014年电工工作总结
2014/11/20 职场文书
Nginx解决403 forbidden的完整步骤
2021/04/01 Servers
浅谈Redis在直播场景的实践方案
2021/04/27 Redis
一劳永逸彻底解决pip install慢的办法
2021/05/24 Python
如何用python清洗文件中的数据
2021/06/18 Python
Apache Hudi 加速传统的批处理模式
2022/04/24 Servers