首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 中文亂碼徹底解決:控制台、phpMyAdmin、PHP 全鏈路統一 UTF-8 實戰

     編輯:MySQL 綜合教學

亂碼本質:字元集轉換鏈路任一環節不匹配

MySQL 處理連接時的編碼流向:


Client (character_set_client)
    ↓ 轉換
Connection (character_set_connection)
    ↓ 轉換
Database/Table/Column (character_set_database)
    ↓ 轉換
Result (character_set_results)

核心原則:連接層字元集 ≥ 客戶端字元集 ≥ 結果字元集,且資料庫/表/列字元集 ≥ 連接層字元集,才能保證無損轉換。

場景 1:控制台 + phpMyAdmin (PMA) 雙修

臨時會話級設置 (重啟失效)


-- 關鍵:客戶端用 gbk 輸入/顯示中文,連接層/庫用 utf8
SET character_set_client = gbk;
SET character_set_connection = utf8;
SET character_set_database = utf8;
SET character_set_results = gbk;

-- 驗證
SHOW VARIABLES LIKE 'char%';

解讀:

  • client=gbk:Windows CMD 默認 GBK,輸入中文正確編碼
  • connection=utf8:內部處理用 UTF-8,容納所有字符
  • results=gbk:輸出回 CMD 用 GBK 顯示正常

永久配置文件 my.cnf/my.ini


[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init_connect = 'SET NAMES utf8mb4'  # 非超級用戶自動執行

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

⚠️ 注意:Windows 控制台若設置為 UTF-8 (chcp 65001),則 client/results 也應為 utf8mb4。

場景 2:資料庫/表/列級字元集統一

檢查當前狀態


-- 資料庫
SHOW CREATE DATABASE db_name;

-- 表
SHOW CREATE TABLE table_name;

-- 列
SHOW FULL COLUMNS FROM table_name;

修正腳本 (生產環境謹慎,大表用 pt-online-schema-change)


-- 資料庫級
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci;

-- 表級 (轉換現有數據)
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

-- 列級精確控制
ALTER TABLE table_name MODIFY COLUMN col_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

場景 3:PHP 應用層連接配置

PDO (推薦)


$dsn = "mysql:host=localhost;dbname=test;charset=utf8mb4";
$pdo = new PDO($dsn, 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_general_ci"
]);

mysqli


$mysqli = new mysqli('localhost', 'user', 'pass', 'test', 3306);
$mysqli->set_charset('utf8mb4');
// 或
mysqli_set_charset($mysqli, 'utf8mb4');

主流框架配置

框架配置示例
Laravel'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci' in config/database.php
Spring Bootspring.datasource.url=...&characterEncoding=utf8mb4&connectionInitSql=SET NAMES utf8mb4
ThinkPHP'charset' => 'utf8mb4' in database config
Django'OPTIONS': {'charset': 'utf8mb4'} in DATABASES

驗證閉環測試

  1. PMA 插入中文 → CMD 查詢顯示正常 → PHP 網頁顯示正常
  2. CMD 插入中文 → PMA 顯示正常 → PHP 讀取正常
  3. PHP 寫入中文 → PMA/CMD 讀取正常
  4. 關鍵檢查:SELECT HEX(col), col FROM table WHERE id=? 確認儲存的十六進位為 UTF-8 編碼 (中文每字 3 字節,Emoji 4 字節)

常見陷阱避雷

現象根因解決
PMA 正常,CMD 亂碼CMD 編碼非 UTF-8,client/results 未設置CMD 執行 chcp 65001 或 SET NAMES gbk/utf8mb4 對應
PHP 寫入正常,讀取亂碼連接字串缺 charset、頁面 meta charset 缺失DSN 加 charset=utf8mb4、HTML
Emoji 存入變 ??表/列為 utf8 (mb3) 非 utf8mb4ALTER TABLE ... CONVERT TO utf8mb4
歷史數據 latin1 存中文雙重編碼 latin1→utf8導出→iconv -f latin1 -t utf8→導入,或 CONVERT TO 配合 BINARY 過渡
修改 my.cnf 重啟無效配置節點錯誤、被後載入文件覆蓋mysql --help | grep my.cnf 確認加載順序、檢查 [mysqld] 節點

最佳實踐總結

  1. 全棧 utf8mb4:Server/Database/Table/Column/Connection/Client/HTML/IDE/File.encoding
  2. 配置文件分層:[mysqld] 設置 server、[client]/[mysql] 設置客戶端工具
  3. 連接初始化 SQL:驅動/連接池配置 SET NAMES utf8mb4 COLLATE utf8mb4_general_ci
  4. 新專案首日鎖定:建庫建表即指定 utf8mb4,避免遷移痛苦
  5. 監控巡檢:定期掃描非 utf8mb4 表、列,納入發布檢查清單

總結

MySQL 中文亂碼不是玄學,而是字元集鏈路管理的缺失。遵循「utf8mb4 全棧統一、連接初始化 SQL 兜底、配置文件分層生效、驗證閉環測試」四步法,配合 HEX() 可視化驗證儲存編碼,即可徹底根治控制台、PMA、PHP 三端亂碼問題。記住:編碼問題 90% 是配置問題,10% 是歷史數據遷移問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved