MySQL和phpMyAdmin与UTF8中文乱码的终极研究

最近笔者勤于备份数据,而且试着把建立在MySQL数据库中的数据在各种平台转来转去,发现了许多的问题,而这些问题在网络上有许多网友问过,但看到很多人找不出答案,因而放弃重装系统或者放弃掉宝贵的旧有数据,那么我相信笔者这一篇文章可能会让您放弃掉坚持在所谓的”UTF-8中文乱码”的迷思。

 

为什么笔者称之为”迷思”,许多使用PHP程序语言搭配MySQL数据库的朋友百分之一百零一会使用phpMyAdmin,但随着MySQL数据库版本的升级,phpMyAdmin数据库管理工具也跟着改版,曾几何时您会发现,原本使用phpMyAdmin工具可以在资料表中看到的中文,变成了乱码。

状况(1) phpMyAdmin未升级前正常,升级后中文变乱码
测试环境

phpMyAdmin版本:2.5.6
MySQL版本:4.1.8-nt
架站环境:Appserv – Win32
网站的预设编码:big5
储存于MySQL的编码:latin1

phpMyAdmin版本:2.6.1 rc-1
MySQL版本:4.1.8-nt
架站环境:Appserv – Win32
网站的预设编码:big5
储存于MySQL的编码:latin1

phpMyAdmin工具版本升级后,结果中文变成乱码。

这种情况并不会影响前台输出中文,所以访客浏览网页时一样正常,差别在于自己在phpMyAdmin时工作并不方便,中文都变成了乱码的原因在于浏览器预设的检视编码不同,原本旧版的2.5.6版以预射big5繁体中文去检视网页,而这个版本以后的新版phpMyAdmin一律都以UTF-8检视,因此才会变成乱码。

这并不会影响到原本储存于数据库中的数据,所以大可不用担心,解决的方法就是使用旧版的phpMyAdmin或者自己写一套数据库管理工具、另外找寻非UTF-8检视的数据库管理软件。

状况(2) 中文UTF-8编码网站,前台浏览正常,phpMyAdmin检视中文变成乱码
测试环境

phpMyAdmin版本:2.6.1 rc-1
MySQL版本:4.1.8-nt
架站环境:Appserv – Win32
网站的预设编码:UTF-8
储存于MySQL的编码:UTF-8

也许很多朋友和笔者和MySQL中文乱码奋战的时候,会看过很多”品种”的中文乱码,为什么phpMyAdmin已经是用UTF-8检视网页了,看到的结果仍旧是火星文,后来经过反复的测试,笔者先规纳出以下的图表作说明:

一般而言,初次安装Appserv架站软件或者在Linux系统中建立MySQL数据库,预设的数据库编码及数据传送方式都会是latin1,从一个不是UTF-8的网页窗体中键入数据,送出到处理的php程序,它取得的字符串就不会是UTF-8编码,而以latin1的编码储存到数据表字段中,最终的编码也是latin1。所以只要用旧版的phpMyAdmin去浏览,看到的一样会是正常的中文字。

而UTF-8网站的处理过程如下图:

在UTF-8网页中的窗体输入数据,其数据在UTF-8网页中可以检视,因为当输入的时候该数据本身就是UTF-8编码的数据,当送出窗体时,这些UTF-8的数据会经过数据库的处理存入字段中,因为MySQL数据库预设传送的编码是latin1,所以它把UTF-8编码数据以latin1编码存入数据表的字段中,而变成乱码。但这个乱码仍然是UTF-8编码的,只是因为被latin1给弄乱了,所以不管是用什么样的编码语系去读取这些字符串,看到的只是乱码,不可能读的出正常的中文字符串。

当前台的程序呼叫时(例如phpbb论坛),MySQL数据库会以latin1将这些乱码”还原”成”正常”的UTF-8中文字。

在latin1的预设编码下,不管怎么在phpMyAdmin更改数据库、数据表、数据表字段的联机校对为utf8_general_ci、utf8_unicode_ci或latin1_swedish_ci等编码,都会是一样的结果,看到的都会是同一款品种的火星文。

如果您想要在phpMyAdmin中看到UTF-8显示正常的中文字,以下有两种解决方案:

更改MySQL预设的联机编码设定
Linux或Unix-like环境

找出 /etc/my.cnf 档案,这个档案是MySQL数据库的设定文件,详细的说明请参阅vbird的WWW服务器#MySQL效能调校,内文有更详细的参数说明,但在此很简单地只要改两个地方就可以让MySQL预设的latin1编码联机方式改成UTF-8。

Win32 – Appserv架站软件

在Windows环境下,则MySQL设定档为my.ini,一般而言存放在c:/window 这个目录底下,同样地找寻上述两个地方将其从latin1改成utf8。

程序语法限定MySQL传送的编码

在此以phpBB2论坛为例,在db.php中第60行以后加入以下指令,告知MySQL都以UTF-8的方式传送数据:

 

笔者将一个UTF-8网站,但MySQL是预设latin1联机的网站,在读取数据库的程序代码中,加入如上图示第62行的程序代码之后,网页上只要是从数据库读出来的中文字都变成了乱码,但试着新增一笔资料,结果如下:

宣告以UTF-8编码联机后,原本好好的UTF-8中文都变成乱码了,因为那些数据原本都是以latin1重编过的UTF8数据,要以latin1编码呼叫才能够还原出原本的UTF-8中文字,但现在强制以UTF-8编码联机,就无法还原了,因此,读者们看到的火星文和数据库中的一模一样地出现在网页上。

宣告以UTF-8编码联机后,所输入的中文字,终于可以在phpMyAdmin中看到,这可是确确实实的UTF-8中文,而不是被latin1编码搞乱的中文字。但是看看上图蓝色框框的部份,不同品种的火星文出现了!但是那些中文字都变成了一堆??????????????问号,这是为什么呢?看看下图,笔者相信读者们的观念就厘清了。

因为在笔者的测试中,只有把第二个字段的联机效对改成UTF-8,其它都一样还是维持latin1的联机效对,也就是说,如果全部以UTF-8编码的方式,确实地在phpMyAdmin等以UTF-8检视的数据库管理软件中看到非乱码的中文字,不但MySQL的联机部份要UTF-8编码,数据表的字段也必须用UTF-8的联机较对,否则会失败。

上图为在MySQL中存入正确的UTF-8中文字的流程,作为本例的一个结束。

状况(3) 中文UTF-8编码网站,在其它Hosting使用mysqldump指令备份,mysql指令汇入正常,但在MySQL 4.x部份中文错乱或汇入失败

相信一定会有读者遇到这种情况,由其是在外国租用Hosting空间或VPS的读者,因为外租的主机是不可能为单一个户去改变系统的默认值的,尤其在英语系国家,存在任何字码,英文字还是英文字,并不会因为说存在不同的编码就变成乱码,所以一律都是预设的。因此,在没办法去要求主机商将MySQL的联机编码改成big5或UTF-8的情况下,一切都只能靠自己解决了。

用mysqldump指令备份数据库是最完整的方法,而且不需要将主机服务停止就可以随时备份,但注意,如果您是采取完美显示UTF-8中文字的解决方案,在没办法使用UTF-8编码联机的状况下,在国外预设为latin1的主机下使用mysql指令汇入数据库会失败!

即使自己的主机预设是latin1,国外的主机预设也是latin1,照理说用mysqldump指令备份,mysql指令还原,会非常顺利,但笔者在测试的过程中发现,某些情况下,部份UTF-8中文字正常,但部份中文字会跳字(变成其它字)和变成乱码,后来笔者发现,这是因为Mysql数据库版本不同而发生的,当笔者在MySQL版本4.1.8(预设联机编码latin1)的情况下使用mysqldump备份,传到国外主机,MySQL版本为5(预设联机编码latin1),用mysql指令汇入,非常地顺利,一下子网站就可以正常运行了,中文字也正常地显示在网页上。

但当笔者要备份国外主机的数据库回自己的主机时,却发现汇入时指令中断,打开备份档将有问题的SQL字句都删除后,再汇入,虽然顺利汇入到数据库中了,但中文字却出现跳字和部份乱码的情况,笔者分析是,版本兼容性的问题,旧版本的备份档可以汇进新版本的MySQL数据库,但从最新版本的数据库备份出的档案要汇进旧版本可能就会发生问题了。

最后笔者将自己测试用的主机MySQL的版本也从4.1.8升级到5系列版本,在国外主机备份的档案,一下子就顺利汇入了,也不再有中文字跳字及部份乱码的情况发生。

附录
MySQL数据库备份语法

如果您是使用Appserv架站软件,那么先从开始列执行输入: cmd

接下来会出现以下窗口,对于不熟DOS接口的读者跟着输入指令就可以了。

 

指令是:

mysqldump – -opt database > backup-file.sql

其中- -opt (这是两个-连在一起,因为本网站程序会将连在一起的减号取代字符串) 是快速完整备份的指令,红色字的database是您要备份的数据库名称,绿色字的 backup-file.sql是汇出而产生的备份档,可自由命名。在Linux也是用这个语法。

MySQL数据库汇入备份文件语法

指令是:

mysql database < backup-file.sql

后记

希望这篇教学文章可以省掉读者们不少时间,笔者花了许多时间在和这些中文乱码搏斗,只求一个安心的备份方式,后来有些心得,仍觉得在网络上还没有一篇文章比较详细具体的说明相关的状况,所以笔者花了约6个小时准备这篇文章,如果可以省下一位读者10个小时的摸索和试误,1000个读者就为这个地球省下10000个小时的时间了, 而笔者需要的是您花30秒回响给我的鼓励与支持,谢谢,希望对您有帮助。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值