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

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 编码
utf8 utf8 gbk gbk 乱码
utf8 utf8 gbk gbk 乱码 是(utf8)
utf8 utf8 gbk gbk 正常 是(gbk)
utf8 utf8 gbk utf8 正常
utf8 utf8 gbk utf8 正常 是(utf8)
utf8 utf8 gbk utf8 乱码 是(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,再储存所以乱码就产生了。

你可能感兴趣的:(测试php源文编码对定义在源文件中的中文字符数据写入Mysql数据库后编码的影响)