环境一:
(1) character_set_results = NULL
(2) character_set_client = UTF-8
(3) character_set_database = gbk
(4) PHP页面编码为UTF-8
执行代码:
<span style="font-family:'Microsoft YaHei';">$str = "我是字符串2"; mysql_query("insert into tb_group(groupid,name,uplevelid,createpersonid) values(9,'{$str}',6,7)") or die(mysql_error());</span>
<span style="font-family:'Microsoft YaHei';">$res = mysql_query("select * from tb_group where groupid = 9"); $result = mysql_fetch_array($res); echo mb_detect_encoding($result["name"]);</span>
整个过程的编码转换:
存储:
(1)要插入数据库的$str为UTF-8编码(因为PHP页面的编码为UTF-8)
(2)执行insert之后,服务器读取character_set_client值(UTF-8), 判断insert过来的数据是否为UTF-8,如果是,则通过,数据前往相应的数据库
(3)在进入数据库时,因为数据库的编码是GBK,而insert过来的数据为UTF-8,因此服务器先将其转为GBK,然后再存入数据库
结果:原本为UTF-8的$str存入数据库后编码变成GBK
读取:
(1)从数据库中取出编码为GBK的结果集
(2)服务器读取character_set_results值(这里为NULL),因为其值为NULL,所以服务器直接将其按GBK编码发往客户端
(3)客户端收到编码为GBK的结果集
总结:
(1)character_set_results = NULL //character_set_results的作用是,指定服务器向客户端返回的结果集的编码。如果它有一个确定的值,比如说“UTF-8”,那么不管结果集的原始编码是什么(比如说是“GBK”),其在被发往客户端之前都会被服务器先转成UTF-8然后在进行发送。但值如果是“NULL”,服务器就不会对其进行转换,是GBK就按GBK发送。
(2) character_set_client = UTF-8 //character_set_client的作用是,指定客户端向服务器发送的查询字符串的编码。如果查询字符串的编码与该值不同,则要插入数据库的值(假如是GBK编码)会是该数据以UTF-8解析的乱码。上例是可以成功的,因为要插入数据库的$str为UTF-8编码,character_set_client的值也为UTF-8,二者相等
环境二
(1) character_set_results = NULL
(2) character_set_client = GBK
(3) character_set_database = gbk
(4) PHP页面编码为UTF-8
执行代码与环境一相同:
执行结果:插入的值(指$str,其为UTF-8编码)是以GBK解析的乱码。
解决:
方法一:$str = iconv("UTF-8","GBK",$str); //将$str从UTF-8编码转换为GBK编码
方法二:mysql_query("SET character_set_client = 'UTF-8'"); //将SET character_set_client值设为UTF-8
环境三:
(1) character_set_results = UTF-8
(2) character_set_client = UTF-8
(3) character_set_database = gbk
(4) PHP页面编码为UTF-8
执行代码与环境一相同
执行结果:成功插入,但从数据库中取出来的值是UTF-8编码(虽然这些值在数据库中都是以GBK编码的)
原因:character_set_results = UTF-8 //在结果集被发送到客户端之前,服务器根据该值将结果集进行了转换
注:在实际编码中,一般都会在数据库连接成功后,执行mysql_query(“SET NAMES 要设置的编码”),将character_set_results,character_set_client以及character_set_connection的值进行统一设置
这里的character_set_results,character_set_client,因为它们值的不同,而造成的一些编码问题在上文中已经讨论过了,对于character_set_connection,在实际的测试中,它的值对编码并没有产生什么影响,所以本文未曾提及,当然这只是个人结论,有兴趣的朋友可以自行对其进行测试。
相关资料:http://dev.mysql.com/doc/refman/5.1/zh/charset.html#charset-database (10.3.6. 连接字符集和校对)