2014-09-12 87 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'"]; 
相關問題