我正在重写我们的数据库类(基于PDO),并且陷入了困境。在PHP和MySQL中使用UTF-8时,我被教会使用SET NAMES utf8
和SET CHARACTER SET utf8
。
在PDO中,我现在想要使用PDO::MYSQL_ATTR_INIT_COMMAND
参数,但它只支持一个查询。
SET CHARACTER SET utf8
是否必要?
答案 0 :(得分:86)
使用SET CHARACTER SET utf8
后使用SET NAMES utf8
实际上会将character_set_connection
和collation_connection
重置为
<{1}}和@@character_set_database
。
manual表示
@@collation_database
相当于
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_client = 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
重置为character_set_connection
,将@@character_set_database
重置为collation_connection
。该手册解释了这些变量的用法:
服务器应该是什么字符集 将陈述翻译成后 收到它?
为此,服务器使用 character_set_connection和 collation_connection系统变量。 它转换由...发送的语句 客户端从character_set_client到 character_set_connection(除了 有文字的字符串文字 介绍人,如_latin1或_utf8)。 collation_connection很重要 文字字符串的比较。对于 字符串与列的比较 值,collation_connection没有 因为列有自己的 整理,有更高的 整理优先权。
总而言之,MySQL用于处理查询的编码/转码过程及其结果是多步骤的事情:
@@collation_database
中编码。character_set_client
转码为character_set_client
character_set_connection
转码为给定数据库列的字符集,并使用列排序规则进行排序和比较。character_set_connection
中编码的结果集(包括结果数据以及结果元数据,如列名等)因此,character_set_results
可能不足以提供完整的UTF-8支持。可以考虑使用SET CHARACTER SET utf8
的默认数据库字符集和使用latin1
- charset定义的列,并完成上述步骤。由于utf8
无法覆盖UTF-8可以覆盖的所有字符,因此您可能会在步骤 3 中丢失字符信息。
latin1
表示的字符,这些字符将会丢失从latin1
转换为utf8
(默认数据库字符集),使您的查询失败。所以我认为可以说latin1
是处理字符集问题的正确方法。即使我可以添加正确设置MySQL服务器变量(所有必需的变量都可以在SET NAMES ...
中静态设置),也可以免除每次连接所需的额外查询的性能开销。
答案 1 :(得分:2)
来自mysql manual:
SET CHARACTER SET类似于SET 名字,但设置
character_set_connection
和collation_connection
来character_set_database
和collation_database
。SET CHARACTER SET x
语句等同于这些语句 三个陈述:SET character_set_client = x; SET character_set_results = x; SET collation_connection = @@collation_database;
答案 2 :(得分:0)
由于需要支持国际字符集,我总是只在数据库创建时设置文本类型字段的字符集。
我也一直使用UTF-8。
在PHP中设置相同:
mb_internal_encoding( 'UTF-8' );