頁面、Request、資料庫、連線、表、欄位 —— **全鏈路單一字符集**(UTF-8 或 GBK),亂碼根除 99%。
| 現象 | 成因層級 | 快速修復 |
|---|---|---|
| 頁面顯示亂碼 | HTTP 響應編碼 | <meta charset="UTF-8"> / header('Content-Type: text/html; charset=UTF-8') |
| 參數傳遞亂碼 | Request 編碼 | request.setCharacterEncoding("UTF-8") (Java) / mysqli_set_charset($link, 'utf8') (PHP) |
| 資料庫存儲亂碼 | 資料庫/表/欄位/連線編碼 | 本文重點解決 |
編譯預設 (latin1)
→ my.cnf [mysqld] default-character-set
→ 啟動參數 --character-set-server
→ CREATE DATABASE 預設字符集
→ USE DATABASE 時 character_set_database
→ CREATE TABLE 預設字符集
→ 定義欄位時預設字符集
# 1. 編輯配置檔
vi /etc/my.cnf (或 /etc/mysql/my.cnf)
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'
# 2. 重啟服務
systemctl restart mysqld
# 3. 驗證
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';
預期輸出:character_set_client/connection/database/results/server = utf8mb4,character_set_system = utf8,collation_* = utf8mb4_unicode_ci。
# 1. 修改配置檔(同場景 A)
# 2. 修改庫級預設
ALTER DATABASE dbname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# 3. 修改表級預設 + 轉換現有欄位
ALTER TABLE tblname CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 注意:CONVERT TO 會實際重寫資料,大表請維護窗口操作
# 4. 僅修改表預設不轉換資料
ALTER TABLE tblname CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# 5. 重啟驗證
SET NAMES utf8mb4; -- 等同於同時設定 client/connection/results
-- 或分別設定
SET character_set_client = utf8mb4;
SET character_set_connection = utf8mb4;
SET character_set_results = utf8mb4;
$mysqli = new mysqli('host', 'user', 'pass', 'db');
$mysqli->set_charset('utf8mb4'); // 必須在查詢前調用
// PDO
$pdo = new PDO('mysql:host=host;dbname=db;charset=utf8mb4', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
utf8 = utf8mb3,僅支援 BMP(基本多文種平面),**不支援 Emoji、生僻漢字**utf8mb4 真正支援 Unicode 4 位元組字符,向下相容utf8mb4 單欄索引 191 字元(InnoDB 767 位元組),5.7.7+ 可調 innodb_large_prefix=ON 放寬至 3072 位元組mysqldump --default-character-set=gbk)