2014-09-12 45 views
4

我们可以在初始化PDO时明确设置字符集为utf8,只需将“charset=utf8”添加到dsn字符串。但是,在使用PDO时,如何明确指定MySQL连接中使用的排序规则?如何在没有SET NAMES的情况下指定与PDO的排序规则?

我不想使用其他查询做到这一点:

SET NAMES utf8 COLLATE utf8_unicode_ci; 

有,而不必诉诸于“集名”什么办法?或者,如果我没有指定排序规则,会不会有问题?

+0

@ kavoir.com我想我对你的问题有一个较短的答案。这是迟了一年,但嘿,我只是从MySQLi准备好的声明中交换了。 – 2015-09-13 19:07:05

回答

1

这里是一个二合一的答案。

您可以在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排序规则,请将其设置为一般的表格或列/字段。

+0

人们应该知道字符集和排序规则是两个不同的东西。 – 2014-09-12 11:35:18

+0

我的表都在utf8_unicode_ci中。我无权访问配置指令。他们会自动受到尊重吗? – 2014-09-12 12:02:06

+0

我已更新我的答案,以显示这些设置是隐含尊重的。 ** SET NAMES UTF-8应该足以隐式设置排序规则utf8_unicode_ci **。希望这可以解决,也许这解释了为什么在使用集合名称时没有人要求整理。顺便说一下,仍然有可能使用另一个排序规则进行查询,这会影响排序。 – 2014-09-12 12:05:00

5

问题:“如何在没有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'"]; 
相关问题