乱码什么的最讨厌了……祸根自从耶和华摧毁巴别塔之时就已经埋下,哪怕这0和1的世界里都不能逃脱这天罚。
PHP上传文件会导致文件名乱码,一般是因为php和系统默认的编码方式不一致,解决办法是用iconv()函数转换一下编码,就像这样:
move_uploaded_file($_FILES["myfile"]["tmp_name"],iconv("UTF-8","gb2312",$filename));
这是使用原生PHP时的处理方法,如果使用Codeigniter的Upload类则需要将do_update()函数中相关的部分改成这样:
if ( ! @copy($this->file_temp, iconv("UTF-8", "gb2312", $this->upload_path.$this->file_name)))
{
if ( ! @move_uploaded_file($this->file_temp, iconv("UTF-8", "gb2312", $this->upload_path.$this->file_name)))
{
$this->set_error('upload_destination_error');
return FALSE;
}
}
UPDATE IN 04/08/2013 :
在样处理过只后有一个问题,在调用do_upload()函数上传文件的时候,会调用set_filename()函数设置函数名,而在set_filename()函数中使用了file_exists()函数来检查要上传的文件是否和已经上传的文件重名。已经上传文件的文件名是GB2312编码,而等待上传的文件的文件名是UTF-8编码,这一来本来同名的文件会被判定为不同名。Upload类本来会为重名的文件在文件名后加上一个数字,但现在这个功能失效了。上传的同名文件没有经过改名,它将直接覆盖原先的文件。解决办法是在set_filename()函数中将$filename中的文件名转换为GB2312编码,然后在函数返回文件名之前再将编码转会UTF-8。
public function set_filename($path, $filename)
{
if ($this->encrypt_name == TRUE)
{
mt_srand();
$filename = md5(uniqid(mt_rand())).$this->file_ext;
}
$filename = iconv('UTF-8', 'GB2312', $filename);//将$filename中的文件名转换为GB2312编码
if ( ! file_exists($path.$filename))
{
$filename = iconv('GB2312', 'UTF-8', $filename);//将编码转回UTF-8
return $filename;
}
$filename = str_replace($this->file_ext, '', $filename);
$new_filename = '';
for ($i = 1; $i < 100; $i++)
{
if ( ! file_exists($path.$filename.$i.$this->file_ext))
{
$new_filename = $filename.$i.$this->file_ext;
break;
}
}
if ($new_filename == '')
{
$this->set_error('upload_bad_filename');
return FALSE;
}
else
{
$new_filename = iconv('GB2312', 'UTF-8', $new_filename);//将编码转回UTF-8
return $new_filename;
}
}