在平时的开发中,我们肯定会遇到中文乱码的问题,在遇到乱码时,我们第一步应该解决这个乱码是由于什么原因引起的,而不是一味的按照网上的一些方法去实践,而是从根源出发。在开发php程序,从mysql数据库中调用出数据打印出来的时候,偶尔也会发生这样的问题。我们排除了下面两种常见的情况:
- 文件编码和系统编码的不同,如wordpress系统是utf8的,而你上传的文件编码是ANSI的,于是会造成乱码;
- meta charset="gbk"而你的输出字符串是utf8的,因此也会引起乱码。
但这两种乱码现象不是本文要讨论的,本文要讨论的是由于PHP和MySQL交互引起的中文乱码问题。这种乱码和上述两种乱码的打印结果是不同的,通常,这种乱码表现为机器乱码,如,而非字符乱码。机器乱码和字符乱码的最大区别就是,字符乱码常常由于编码不同导致解析错误,用错误的字符来代替想要输出的字符。而机器乱码则是由于无法识别而打印出比较奇怪的图形乱码。
接下来我们来看下怎么解决,涉及到PHP和MySQL交互中的中文乱码问题的细节包括:
- 数据库Database的字符集
- 数据表Table的字符集
- 字段的字符集
- PHP连接MySQL进行查询、插入等mysql_connect操作时执行的字符集命令
- 输出结果的字符集
首先,我们利用phpmyadmin登录mysql,进行数据库管理。在数据库Database的操作选项中可以修改数据库的“整理”,一般的选项是utf8_general_ci和gbk_chinese_ci,有的时候也选择gb2312_chinese_ci。
接着,进入到某个表Table的操作选项,在“表选项-整理”中可以修改这个值,一般选项如上。
再接着,在进入某个表后,点击结构选项,这时会列出该表的所有字段,点击字段后面的“修改”进入字段属性修改页面,在“整理”中选择上述的值。
接下来是PHP连接中的字符集命令,即在查询或插入mysql_query之前,先执行一个SET命令SQL,让数据库调整到规定的字符集,具体代码如下:
mysql_connect($dbhost, $dbuser, $dbpw); mysql_query("SET NAMES 'utf8/gbk'"); mysql_query("SELECT * FROM `mytable`");
这几乎包含了所有需要调整的地方,关于上述第5点,其实是和部分系统中的特殊方法相关,例如有的系统提供快捷的数据获取方法,如db_get_row('mytbale',array('ID' => 3),'utf8')类似的,因为不同的系统所兼容的字符集不同,所以可能存在这个环节。但如果不考虑这个环节,前面讲到的四个条件足以帮助我们解决这个问题。
我们来看下一些字符集组合:
database:utf8 + table:utf8 + colum:utf8 + set:utf8 => 插入正常,输出正常 database:utf8 + table:utf8 + colum:utf8 + set:gbk => 插入乱码(插入乱码指PHP执行插入命令后数据库中该字段值也是乱码),输出乱码,注意这个地方还有点不同,如果原来在数据库中正常的,输出时是字符乱码,如果数据库中不正常的,输出时是机器乱码 database:utf8 + table:utf8 + colum:gbk + set:gbk => 插入乱码,输出正常(这是一个值得注意的现象,因为你看到输出正常的时候,应该再检查一下数据库) database:utf8 + table:gbk + colum:gbk + set:gbk => 插入乱码,输出正常 database:gbk + table:gbk + colum:gbk + set:gbk => 插入乱码,输出正常 database:gbk + table:utf8 + colum:gbk + set:gbk => 插入乱码,输出正常 database:gbk + table:utf8 + colum:utf8 + set:gbk => 插入乱码,输出也是乱码 database:gbk + table:utf8 + colum:utf8 + set:utf8 => 插入乱码,输出正常 database:gbk + table:gbk + colum:utf8 + set:utf8 => 插入正常,输出正常 database:gbk + table:gbk + colum:gbk + set:utf8 => 插入正常,输出正常
从中我们可以发现,php执行端是绝对的关键,必须与当前的php文件和meta charset一致即可。同时,需要避免由于库和表字符集不对称导致的插入乱码。