我們可以在初始化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