iT邦幫忙

0

使用 PDO 無法存 emoji 文字到資料庫?Illegal mix of collations

PHP Fatal error:  Uncaught PDOException: SQLSTATE[HY000]: General error: 1267 Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='

文字儲存都正常
但是丟 https://getemoji.com/ 時(???)
就會報 500 Internal Server Error 錯誤
我是像這樣丟資料庫進去的

$stmt = $pdo->prepare(
          "UPDATE `setting` SET
          `data_2` = :xxx
          WHERE `id` = :target_id "
        );
        $stmt->execute([
          'xxx' => $icon,
          'target_id' => 'setting-page-cover'
        ]);

1 個回答

0
淺水員
iT邦新手 3 級 ‧ 2019-08-07 22:27:06
最佳解答

這樣試試:

剛建立完 pdo 物件後
先執行 $pdo->query("set names utf8mb4");
讓連線也是用 utf8mb4 傳輸

或是在建立 PDO 物件時直接指定 charset

$pdo=new PDO(
        'mysql:host=localhost;dbname=example;charset=utf8mb4',
        'user',
        'pwd'
    );
看更多先前的回應...收起先前的回應...
小松菜奈 iT邦研究生 4 級 ‧ 2019-08-08 00:29:45 檢舉

目前 charset 設定的是 utf8

raytracy iT邦大神 1 級 ‧ 2019-08-08 07:21:10 檢舉

Mysql utf8 長度只有 3 bytes 不能存 emoji,
必須用 4 bytes 空間的 utf8mb4

用 SQL 指令看一下你有甚麼地方沒改到:

SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';

正常應該這樣:

+--------------------------+--------------------+
| Variable_name            | Value              |
+--------------------------+--------------------+
| character_set_client     | utf8mb4            |
| character_set_connection | utf8mb4            |
| character_set_database   | utf8mb4            |
| character_set_filesystem | binary             |
| character_set_results    | utf8mb4            |
| character_set_server     | utf8mb4            |
| character_set_system     | utf8               |
| collation_connection     | utf8mb4_unicode_ci |
| collation_database       | utf8mb4_unicode_ci |
| collation_server         | utf8mb4_unicode_ci |
+--------------------------+--------------------+

或把Post過來的資料在存進資料庫前,做一次urlencode,讀取出來print到頁面前再decode,就能保証emoji跟unicode標準字元都是一樣的處理方式

淺水員 iT邦新手 3 級 ‧ 2019-08-08 13:00:19 檢舉

emoji 大部分 unicode 都會超過 0xffff(少數的中文罕見字也會超過這個值)
當 unicode 超過 0xffff ,utf8 編碼後會超過 3 個 byte,這時就必須用 utf8mb4 了。

我要發表回答

立即登入回答