我重新编写了我们的数据库类(基于PDO),并陷入了困境。我被教导如何在PHP和MySQL中使用SET NAMES utf8以及SET CHARACTER SET utf8在UTF-8中使用。
SET NAMES utf8
SET CHARACTER SET utf8
在PDO中,我现在想使用PDO::MYSQL_ATTR_INIT_COMMAND参数,但它仅支持一个查询。
PDO::MYSQL_ATTR_INIT_COMMAND
有SET CHARACTER SET utf8必要吗?
利用SET CHARACTER SET utf8使用后SET NAMES utf8实际上会重置character_set_connection,并collation_connection以 @@character_set_database和@@collation_database分别。
character_set_connection
collation_connection
@@character_set_database
@@collation_database
该手册指出
SET NAMES x 相当于
SET NAMES x
SET character_set_client = x;
SET character_set_results = x; SET character_set_connection = x;
和SET CHARACTER SET x相当于
SET CHARACTER SET x
SET character_set_results = x; SET collation_connection = @@collation_database;
而SET collation_connection = x同时在内部执行SET character_set_connection = <<character_set_of_collation_x>>和SET character_set_connection = x内部还执行SET collation_connection = <<default_collation_of_character_set_x。
SET collation_connection = x
SET character_set_connection = <<character_set_of_collation_x>>
SET character_set_connection = x
SET collation_connection = <<default_collation_of_character_set_x
所以基本上你重新character_set_connection给@@character_set_database和collation_connection给@@collation_database。手册说明了这些变量的用法:
服务器在收到语句后应将其转换为什么字符集? 为此,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的语句从character_set_client转换为character_set_connection(具有诸如_latin1或_utf8之类的介绍符的字符串文字除外)。collation_connection对于比较文字字符串很重要。对于将字符串与列值进行比较,collation_connection无关紧要,因为列具有自己的排序规则,排序规则优先级更高。
服务器在收到语句后应将其转换为什么字符集?
为此,服务器使用character_set_connection和collation_connection系统变量。它将客户端发送的语句从character_set_client转换为character_set_connection(具有诸如_latin1或_utf8之类的介绍符的字符串文字除外)。collation_connection对于比较文字字符串很重要。对于将字符串与列值进行比较,collation_connection无关紧要,因为列具有自己的排序规则,排序规则优先级更高。
综上所述,MySQL用于处理查询的编码/代码转换过程及其结果是一个多步骤的过程:
character_set_client
character_set_results
因此,可能情况是a SET CHARACTER SET utf8不足以提供完整的UTF-8支持。考虑latin1使用utf8-charset 定义的和的默认数据库字符集和列,并执行上述步骤。由于latin1无法覆盖UTF-8可以覆盖的所有字符,因此在步骤 3中 可能会丢失字符信息。
latin1
utf8
因此,我认为可以肯定地说这SET NAMES ...是处理字符集问题的正确方法。即使我可能会补充说,正确设置MySQL服务器变量(所有必需的变量都可以在中静态设置my.cnf)可以使您免除每次连接所需的额外查询的性能开销。
SET NAMES ...
my.cnf