首页 > 代码库 > 对于PHP+MYSQL的中文乱码问题的理解和困惑

对于PHP+MYSQL的中文乱码问题的理解和困惑

  首先先说下现在已调试好的无乱码配置。mySQL的dos的客户端编码配置为(通过set names gbk 语句设置):

        character_set_client | gbk
        character_set_connection | gbk
        character_set_database | utf8
        character_set_filesystem | binary
        character_set_results | gbk
        character_set_server | utf8
        character_set_system | utf8

在php文件中设置显示编码为utf-8。通过查询语句获取知,除filesystem外,其它编码方式都是utf-8。由于每次重启mysql或重启mysql命令行客户端时,编码方式都会重置为安装所选择的默认编码方式(本例中采用了utf8编码。在软件编码配置页,默认为latin1,通过选择第三项(manual)配置编码语言。这点对于初学者很重要!),所以每次都需要手动通过set names gbk来设置编码。

  接下来再科普下character_set_connection、character_set_results、 character_set_client的含义。通常的使用中,character_set_client,character_set_connection这两个变量的值是一样的,也就是说查询不需要进行编码转换。这样看来变量character_set_connection有些多余。当查询进入时,查询会被服务器从 character_set_client转换到character_set_connection,当查询执行时,查询会被服务器从 character_set_connection转换到列字符集。查询返回时,数据直接被服务器从列字符集转换到 character_set_results。由此可见,这三个参数主要用于客户端与服务器进行交互的过程中编码格式的转换。在进行编码格式设置时,这三个必须保持同步,否则就会出现乱码。character_set_server ,character_set_system这两项是服务器参数,这里暂时不作讨论,默认为utf-8编码格式。

 

  下面说说我的理解和困惑。

  问题:当命令行客户端通过set names utf8编码进行中文输入存储时,命令行客户端能正常显示中文,php编写的网页不能正常显示中文。但是网页中选择GB2312编码显示时,中文恢复正常显示。类似的,当命令行客户端通过set names gbk编码进行中文输入存储时,命令行客户端能正常显示中文,php编写的网页可以正常显示中文(网页默认utf-8)。

  理解:命令行客户端默认是gbk输入方式。当系统设置为utf8时,通过insert命令对数据库添加数据时,实际上是将gbk强制转换为utf8,然后存储进数据库。php网页仍然认为是utf8码,所以显示乱码。而当网页强制为GB2312码时,相当于又进行了一次转码,所以又显示正常了。而对于命令行客户端,我们实际是通过character_set_results参数控制显示的。当选择utf8码时,则在utf8码设置下的插入的中文显示正常,当选择gbk码时,则在gbk码设置下的插入的中文显示正常。问题的症结点在于,不管mySQL编码怎么设置,当我们通过命令行客户端输入时,它实际输入的内容是gbk码的。这也解释了为什么在设置为utf8码时,只能输入部分中文字符。如,在utf8码下无法输入中文字符串“男孩”。

  当然,上述也是我的一些个人理解和猜测。在进一步学习mySQL后,如果发现上述有偏颇或错误。我将会后续进行更正。

   此文参考了两处文章,感谢如下两位同学的分享,网址如下:

  http://qq695198038.blog.163.com/blog/static/1662751322012329113552221/

  http://www.2cto.com/database/201108/101151.html

  http://www.cnblogs.com/xwdreamer/archive/2012/07/11/2585993.html