set names utf8的内部执行原理

目录

MySQL 字符集配置

在 my.ini(Windows)或 my.cnf 中设置:

[mysql]
default-character-set=utf8

[mysqld]
default-character-set=utf8

但即使设置了这些,直接连接时仍可能遇到乱码。查看当前字符集设置:

show variables like "character_set_%";

可能看到:

character_set_client     latin1
character_set_connection latin1
character_set_database   utf8
character_set_results    latin1
character_set_server     utf8
character_set_system     utf8

SET NAMES UTF8 的作用

在连接数据库后、读取数据前,执行:

SET NAMES UTF8;

PHP 中:

mysql_query("SET NAMES UTF8");  // 必须在 mysql_connect() 之后

这等同于:

SET character_set_client = utf8;
SET character_set_connection = utf8;
SET character_set_results = utf8;

数据传输路径

输入路径:client → connection → server
输出路径:server → connection → results

问题出在三个关键字符集上。以输出乱码为例,server 中的 utf8 数据经过 connection 转为 latin1,再转为 latin1 的 results,最后 utf-8 页面再转一次。两种字符集不兼容时,转化过程是不可逆的。

注意

SET NAMES UTF8 的作用仅是临时的,MySQL 重启后恢复默认值。从服务器配置角度无法通过配置完全省略这行代码,所以为了兼容性,建议每次连接后都执行一次 SET NAMES UTF8。

#mysql #php