如何在没有SET NAMES的情况下使用PDO指定排序规则?

时间:2014-09-12 11:25:26

标签: php mysql pdo

我们可以在初始化PDO时将char设置显式设置为utf8,只需将“charset=utf8”添加到dsn字符串即可。但是,如何在使用PDO时明确指定MySQL连接中使用的排序规则?

我不想使用其他查询来执行此操作:

SET NAMES utf8 COLLATE utf8_unicode_ci;

有没有办法不诉诸“SET NAMES”?或者,如果我没有指定排序规则会有任何问题吗?

3 个答案:

答案 0 :(得分:6)

问题:“如何在没有SET NAMES的情况下使用PDO指定排序规则?..如何在使用PDO时明确指定MySQL连接中使用的排序规则?”

答案:如果不使用SET NAMES或类似的东西,你就是不能这样做。在PDO构造函数的PDO::MYSQL_ATTR_INIT_COMMAND数组中使用$options 明确直接设置连接整理 的唯一途径在您的连接代码中使用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'"];

答案 1 :(得分:5)

这是一个二合一的答案。

您可以在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名称与db中设置的排序规则一起使用。


您的评论:

  

“人们应该知道字符集和整理是两回事。”

让我们从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;

如果在列上指定了CHARACTER SET 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整理,请将其设置为一般的表格或列/字段。

答案 2 :(得分:0)

使用此---完成---- enter image description here

$pdo = new PDO('mysql:host=localhost;dbname=vocabulary;charset=utf-8', "root", "", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

并在HTML页面中使用

<meta charset="UTF-8">