我们可以在初始化PDO时明确设置字符集为utf8,只需将“charset=utf8
”添加到dsn字符串。但是,在使用PDO时,如何明确指定MySQL连接中使用的排序规则?如何在没有SET NAMES的情况下指定与PDO的排序规则?
我不想使用其他查询做到这一点:
SET NAMES utf8 COLLATE utf8_unicode_ci;
有,而不必诉诸于“集名”什么办法?或者,如果我没有指定排序规则,会不会有问题?
我们可以在初始化PDO时明确设置字符集为utf8,只需将“charset=utf8
”添加到dsn字符串。但是,在使用PDO时,如何明确指定MySQL连接中使用的排序规则?如何在没有SET NAMES的情况下指定与PDO的排序规则?
我不想使用其他查询做到这一点:
SET NAMES utf8 COLLATE utf8_unicode_ci;
有,而不必诉诸于“集名”什么办法?或者,如果我没有指定排序规则,会不会有问题?
这里是一个二合一的答案。
您可以在DSN或MYSQL_ATTR_INIT_COMMAND(连接选项)中设置此项。
我认为DSN更好。
$connect = new PDO(
"mysql:host=$host;dbname=$db;charset=utf8",
$user,
$pass,
array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
)
);
如果指定UTF-8
您正在使用的utf8_general_ci
默认排序规则的工作,除非你的数据库表或字段使用不同的东西。
如果你想整个服务器与此默认排序规则作出回应,然后使用配置指令:
collation_server=utf8_unicode_ci
character_set_server=utf8
所以你不必每次指定它的连接。
归类影响字符的排序,并设置在数据库的表和字段中。 当查询表格时,这些设置是受尊重的。确保它们已被设置。 使用UTF-8名称和您的数据库中设置的排序规则。
您的评论:
“人们应该知道的字符集和校对规则是2米不同的东西。”从MySQL Manual
让我们引用来证明这一点:
一个
SET NAMES 'charset_name'
语句相当于这三个 声明:SET character_set_client = charset_name; SET character_set_results = charset_name; SET character_set_connection = charset_name;
设置
character_set_connection
到CHARSET_NAME也隐含设置collation_connection
到默认排序规则为 charset_name。
我的回答:它隐含地起作用,除非你的表格明确地改变了这个。从评论
问:
如何确保我不要把事情搞得一团糟我的表是不是 默认排序规则utf8_general_ci?
实施例:柱核对覆盖表核对
CREATE TABLE t1
(
col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci
) CHARACTER SET latin1 COLLATE latin1_bin;
如果字符集X和COLLATE Y都是在一个列中指定,字符集X和归类Y的使用。该列具有字符集utf8
和排序规则utf8_unicode_ci
,如表列中所指定的,而该表位于latin1 + latin1_bin中。
实施例:一般表归类用于
如果上一列没有明确指定归类/字段,则该表归类用于:
CREATE TABLE t1
(
col1 CHAR(10)
) CHARACTER SET latin1 COLLATE latin1_bin;
COL1具有核对latin1_bin。
如果您想要utf8_unicode_ci
排序规则,请将其设置为一般的表格或列/字段。
人们应该知道字符集和排序规则是两个不同的东西。 – 2014-09-12 11:35:18
我的表都在utf8_unicode_ci中。我无权访问配置指令。他们会自动受到尊重吗? – 2014-09-12 12:02:06
我已更新我的答案,以显示这些设置是隐含尊重的。 ** SET NAMES UTF-8应该足以隐式设置排序规则utf8_unicode_ci **。希望这可以解决,也许这解释了为什么在使用集合名称时没有人要求整理。顺便说一下,仍然有可能使用另一个排序规则进行查询,这会影响排序。 – 2014-09-12 12:05:00
问题:“如何在没有SET NAMES的情况下指定与PDO的排序规则?..如何在使用PDO时明确指定MySQL连接中使用的排序规则?
答:只是不能使用SET NAMES或类似的东西。该$options
阵列的PDO constuctor在使用PDO::MYSQL_ATTR_INIT_COMMAND
是使用PDO 只有这样,才能明确设置连接校对直接在您的连接代码。否则,你将依赖的不是显式语法(这不是问题的答案)。当然,其他任何方法都不那么直接。
某些版本的MySQL(5.1)具有两个3字节的unicode uft8归类(unicode和general)。只需在$ dsn字符串中使用utf8将不会明确选择“unicode”版本或utf8归类的“常规”版本。 PDO不是心灵读者。
因此,您的选项字符串可能是这个样子:
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8' COLLATE 'utf8_unicode_ci'"];
或
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8' COLLATE 'utf8_general_ci'"];
的MySQL更高版本具有4个字节的UTF8 Unicode的实现。在这里,你可以指定utf8mb4,而不是uft8。
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'"];
@ kavoir.com我想我对你的问题有一个较短的答案。这是迟了一年,但嘿,我只是从MySQLi准备好的声明中交换了。 – 2015-09-13 19:07:05