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'
]);
這樣試試:
剛建立完 pdo 物件後
先執行 $pdo->query("set names utf8mb4");
讓連線也是用 utf8mb4 傳輸
或是在建立 PDO 物件時直接指定 charset
$pdo=new PDO(
'mysql:host=localhost;dbname=example;charset=utf8mb4',
'user',
'pwd'
);
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標準字元都是一樣的處理方式
emoji 大部分 unicode 都會超過 0xffff(少數的中文罕見字也會超過這個值)
當 unicode 超過 0xffff ,utf8 編碼後會超過 3 個 byte,這時就必須用 utf8mb4 了。