UTF8,PHP 以及 MySQL
在 Akra’s DevNotes 看到的这篇文章,刚好最近两篇文章都是将乱码的,于是也搬过来了。
问题:
存储多字节字符到 MySQL,或者从 MySQL 中读取类似的数据,出现乱码。
解决方法:
在任何地方都使用 UTF-8 编码。
> 浏览器
1 | <?php header("Content-type: text/html; charset=utf-8"); ?> |
或者使用一个 meta 标签来设置HTTP协议的响应头报文:
1 | <meta http-equiv="content-type" content="text/html; charset=utf-8" /> |
这行 HTML 代码会通知客户端浏览器,文件类型为 html,且使用了 utf-8 编码。
header()函数所发送的 HTTP,从优先级上面看,由于先一步被浏览器所接受,所以优先级更高(不知道可不可以这么说)。
这里需要注意的是,如果服务器端使用的是 Apache 1.3.x,你应该留意一下命令 AddDefaultCharset:
1 2 3 4 | AddDefaultCharset GB2312 # 关闭默认字符集 # AddDefaultCharset Off |
这行命令会强制该服务器上的所有网页使用 GB2312,它的优先级比 META 标签要高,但是比 header() 函数低,这就是为什么有时候明明设置了 META 标签,但是死活不起作用的原因。
> MySQL
设置你的数据表使用 utf8_general_ci,这是 utf8 编码的一种校验规则(Collation),请注意 Collation 和 Character Set,是不同的概念,Collation 是指某字符集内字符的之间的对比规则,它会影响到数据的排序方式,一种字符集通常会包含多种校验规则。
设置数据表的 Collation,这是服务器端的设置,你还需要保证客户端连接的编码也同样是 UTF8。
1 2 3 4 5 6 7 | <?php // for mysql mysql_set_charset('utf8'); // or for mysqli: mysqli_set_charset('utf8'); ?> |
以下方式你可能更熟悉:
1 2 3 4 5 | <?php $dbAdapter->query("SET NAMES UTF8"); $dbAdapter->query("SET CHARACTER SET UTF8"); ?> |
两种方式类似,有些也有差别,这里不多说了,有兴趣可以参考 MySQL 的文档:
http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html
> PDO & Zend_Db
Zend/PDO 中如何设置连接编码,可以参考我之前的文章。
经过这一番折腾以后,你的乱码问题应该差不多就搞定了。
恩,这个我前几天知道的。
恩。。。我也是都用utf-8,所有文件的编码用utf-8 , mysql 也用,meta也用。。从来没出现过乱码的情况。
以前做国外的项目都是英文,不存在编码的情况。。。现在做大陆的项目全是要处理中文。。。养成全部utf-8的习惯好。