测试php源文编码对定义在源文件中的中文字符数据写入Mysql数据库后编码的影响

来源:互联网 发布:淘宝如何入驻全球购 编辑:程序博客网 时间:2024/04/27 19:08

MYSQL数据库的编码是相当灵活,可以随意定义到数据库的默认编码,表的默认编码,字段的编码。

        但从数据的本质来讲,无论任何编码都是一堆字节数据。那mysql是根据什么配置来确定我们数据的编码,帮我们正确去储存数据。特别是对于多字节编码的数据,中文,韩文,日文。当然可以采用utf-8,或ucs2来适应这些编码,而且工作量也大为减少。但实际情况中有可能用到本地编码来定义数据表、字段编码,例如我们的实际输入的数据编码是gbk,但数据库或表或字段是utf-8,,而我们又没执行set names 编码名来确定我们数据的编码,mysql去采用默认的default-character-set来决定是否要转码再储存。又或者我们程序中转码再执行sql储存数据。而这一切都是为了保证我们储存到数据库编码的正确。所以set names 编码名和视图编码、视图输入数据的编码一致的时候我们程序就不会显示乱码。从mysql手册中查得SET NAMES 'charset_name'  和 SET CHARACTER SET charset_name是类似的。他们的区别如下:

 

SET NAMES 'charset_name'  等价

SET character_set_client = charset_name;

SET character_set_results = charset_name;

SET character_set_connection = charset_name;

 

SET CHARACTER SET charset_name 等价

SET character_set_client = charset_name;

SET character_set_results = charset_name;

SET collation_connection = @@collation_database;

 

由上可见,两者作用是类似的,只是第二个命令多了collation_connection 为连接校对字符集。

 

对于这两个命令,我们可以简单的理解:

  • character_set_client告诉mysql:我们的程序向你发送的数据是什么字符集编码的,如果和要存储的字段的编码不一样,你要帮我转码再储存。
  • character_set_results告诉mysql:我的程序需要显示的数据是什么字符集编码的,如果你储存在库中的编码和我要的编码不一样,你要为我转码再返回给我。
  • SET character_set_connection告诉mysql:我连接你mysql的连接过程中使用的是什么字符集编码,你不要搞混了。
  • SET collation_connection告诉mysql:我的数据校对采用什么字符集编码,你排序、索引的时候要按这个来搞。

前些天在tp群中,有群友提出了特定编码的php源文件中,定义的sql数据保存到数据库中数据后的编码问题,以及乱码的产生原因。于是做了以下一个简单的实验。

-----------------------------------------------------------------------------------------------------------------

测试表结构

CREATE TABLE `hello` (         `id` int(32) NOT NULL AUTO_INCREMENT,          `username` varchar(32) CHARACTER SET gbk NOT NULL,           `password` varchar(32) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

-----------------------------------------------------------------------------------------------------------------

测试写入数据,定义在源文件中:

 

$conn = mysqli_connect('localhost','root','mydb','pss_demo');//由实际测试决定是否执行该行/*mysqli_query($conn,'set names gbk;');*/mysqli_query($conn,"insert into hello values(null,'你妹','12345678');");mysqli_commit($conn );

 

-----------------------------------------------------------------------------------------------------------------

测试结果:

 默认客户端编码数据表编码字段编码源文件编码是否乱码是否set names 编码utf8utf8gbkgbk乱码否utf8utf8gbkgbk乱码是(utf8)utf8utf8gbkgbk正常是(gbk)utf8utf8gbkutf8正常否utf8utf8gbkutf8正常是(utf8)utf8utf8gbkutf8乱码是(gbk)







 

 

 

 

结论:对于定义在源文件的中文数据是按源文件的编码来储存的,发送给mysql服务器时候是直接发送定义好的数据,编码未曾改变。假如没有set names 编码,会采用mysql默认的default-character-set来进行编码的检查转换。假如发送的数据和mysql设置的默认default-character-set不一致,mysql又执行从default-character-set到实际的字段的编码转换,所储存的数据就会是乱码。转码始终存在,比如说,你发出的sql语句包含的中文是gbk编码的,而你没set  names,假如mysql的默认default client charset 是utf8,那么mysql就会把你发出gbk数据当做utf8来进行处理。所储存到的字段又是gbk的话,mysql会将你的gbk数据当是utf8,执行从utf8转码到gbk,再储存所以乱码就产生了。

原创粉丝点击