Content Entry

基于mysql + php 的 utf-8 应用

Published: 2007-03-14 Categories: Tech Tags: MySQL PHP UTF-8

SmartKit 0.0.26实现了utf-8的应用,小结一下:

utf-8是unicode的一种变长字符编码,由Ken Thompson于1992年创建。utf-8用1到6个字节编码unicode字符,这种编码致力于把全球的语言纳入一个统一的编码...

详细信息参考: The Basics of UTF-8
http://www.codeguru.com/cpp/misc/misc/multi-lingualsupport/article.php/c10451/

使用utf-8的优点:
支持多语言,对xml、javascript、ajax等兼容性好,避免让人吐血的中文乱码问题.

实现mysql php的utf-8应用,涉及三个方面:
1. 使用正确的数据库连接编码
很多人开始接触php时,习惯性的使用 mysql_connect() mysql_select_db() 后便开始操作SQL,则在mysql4.0及其之前当然没有问题。从mysql 4.1开始有了 Character Set 与 Collation 的慨念, 而 4.0 及其以前的mysql中,php默认使用拉丁文(latin)来储存中文,而4.1开始默认的编码是utf-8,于是"中文乱码"出现了。
通过重设mysql的默认编码可以满足需求,但不推荐,因为utf-8似乎更优秀、符合标准、利于兼容。
所以比较好的方式是在mysql_connect()之后,设置连接字符编码:mysql_query("SET character_set_connection=utf8, character_set_results=utf8, character_set_client=utf-8;");

2. php、html等文本文件的内码需要转换为utf-8
Windows下文本文件默认内码为ANSI,用记事本"另存为"文本时回出现"Encoding"选项,可以选择使用"utf-8"; 文件比较多的情况下可以使用工具批量转换.

但这里又会出现一个问题,转化为utf-8的php脚本放到server执行时,报"Cannot send session cookie - headers already sent by..."错误,并且错误出在 "line 1",说明脚本的第一行输出字符,找遍 line 1,也看不到有任何输出!?
这里引入一个新的问题: "BOM (Byte Order Mark)",BOM是一个字符,它表明unicode文本的utf-16,utf-32的编码字节顺序(高字节低字节顺序)和编码方式(utf-8,utf-16,utf-32,其中utf-8编码是字节顺序无关的),通过查看文本的二进制可以发现文件前面多出来如EFBBBF、FEFF、FFFE等声明,这就是php报出“line 1”的原因。但是Windows的很多编辑器会默认加入这个字符,对于php应用来说,必须去掉BOM,因为我们不能容忍没有session或cookie的php!
我找到了一个小工具来批量转换ANSI->utf-8,并同时去掉BOM, 可结果很糟糕,转换到utf-8没有大问题,可只有少部分文件的BOM被正确的去掉,我抛弃了这个工具;于是换成比较稳定可靠
的UltraEdit来处理(UltraEdit会将utf-8的文本自动转换为utf-16,在设置中去掉这个),另存为"utf-8 无BOM", 但依然不理想,还有部分不能顺利转换,更另人不解的是,在用UltraEdit编辑utf-8的文本是,我的UltraEdit开始平凡的出现"未响应"一直崩溃。
最后使用Zend Studio做编辑器,可以流畅的edit了。

3. html中Content-Type使用charset=utf-8
ibm-developerworks文章:UTF-8 字符处理在 Web 开发中的应用
http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/?ca=wa-t10

end

comments loading