转码UTF-8时遇到的PHP&MySQL的字符集问题

转码UTF-8时遇到的PHP&MySQL的字符集问题

这几天想给网站加一个WAP版,根据wml协议的规定,必须符合XML标准,采用utf8编码字符。这事说起来简单但做起来难,昨天折腾了大半天的,首先倒腾一些库的PHPtemplate文件,把ANSI转成UTF-8,同时还要去掉UTF-8规定的开头三字节长度标识符,否则PHP无法识别;然后研究和调整数据库编码,找了很多资料钻研MySQL编码的细节,排列组合式的测试,最后发现被误导了,根本不用研究那么多,用最简单的方式就可以了。无论如何,最后总算是大功告成了。在网上查资料的时候,发现很多都语焉不详,这里把心得总结一下。

网站采用PHP脚本语言,是基于Discuz搭建的,基本编码是前台和数据处理采用GBKANSI),数据库采用MySQL默认的latin1。我发现Discuz存储和处理数据库编码的方式相比文章《MySQL的字符集问题》所描述的情形来说比较简单粗暴,仅仅SET NAMES 'latin1',然后不分青红皂白把字符串往里扔,而不管什么character_set_clientcharacter_set_connectioncharacter_set_results还是collation_connection。虽说简单粗暴,但是这其实是MySQL推荐实现的方式,即数据库具体的数据字符集保持和SET NAMES的参数一致,这样进行读写是兼容性最好的。尽量不要采用对这

三个参数分别设置不同值的方式,那样会带来潜在的bug和混乱。

由于SET NAMES ‘x’ 等效于:
SET character_set_client = x;
SET character_set_results = x;
SET character_set_connection = x;
SET character_set_connection = x; 执行的同时也自动指定了collation_connectionx的默认字符集collation(如xutf8collation_connectionutf8_general_ci),因此SET NAMES必须和数据列中指定的字符集一致,否则会报错。

SET CHARACTER SET则不同,但它将连接的collation_connectioncollation_connection分别设置为默认数据列的字符集和collation

SET CHARACTER SET x 等效于:
SET character_set_client = x;
SET character_set_results = x;
SET collation_connection = @@collation_database;
SET collation_connection
同时也会自动设置character_set_connection为同样的值,这样SET CHARACTER SET就无论如何设置,在进行数据库存取操作的时候都不会报错。但是逻辑上就需要程序员自己来保证。

数据库管理程序并不负责给你的字符串进行编码,你的SET只是告诉数据库:哥们,你就按我说的编码那么处理吧,出了事我负责。

由于Discuz这种简单粗暴而又由于其兼容性而值得推荐的对字符集的处理方式,所以对于之前的网站系统,前台数据编码处理流程:
网站直接将GBK扔给数据库   |SET character_set_client = 'lain1'    |SET character_set_connection = 'lain1'
存储及访问:GBK--------------->数据库认为其为latin1进行接收---------------->latin1编码存储

SET character_set_connection = 'lain1' |SET character_set_results = 'lain1' |网站直接把latin1GBK输出
读取:数据库读取编码为latin1的数据---------------->以编码为latin1输出------------------>GBK

所以,在写WAP页面或者有要把网站转成UTF-8编码的需求的时候,其实很简单,只要在脚本程序里,把字符串编码转换一下就可以了。比如这里我们用PHP,那么用iconv或者mbstring都可以:

$str = iconv("gbk//IGNORE", "UTF-8//IGNORE", $str);
$str = mb_convert_encoding($str, "UTF-8", "gbk");

现总结到这里,在下才疏学浅,如有纰漏,还望指正。

 

 

你可能感兴趣的:(转码UTF-8时遇到的PHP&MySQL的字符集问题)