UTF8,PHP 以及 MySQL

Mar 22nd, 2009 | Filed under PHP

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 中如何设置连接编码,可以参考我之前的文章。

经过这一番折腾以后,你的乱码问题应该差不多就搞定了。
😛

  1. 华晨
    Aug 23rd, 2009 at 12:55
    Reply | Quote | #1

    恩,这个我前几天知道的。

  2. carson
    Dec 12th, 2009 at 00:48
    Reply | Quote | #2

    恩。。。我也是都用utf-8,所有文件的编码用utf-8 , mysql 也用,meta也用。。从来没出现过乱码的情况。
    以前做国外的项目都是英文,不存在编码的情况。。。现在做大陆的项目全是要处理中文。。。养成全部utf-8的习惯好。

Comments are closed.