MySQL 4.1+ 引入多語言支援,但 PHP 操作中文亂碼問題長期困擾開發者。本文系統分析亂碼根因,提供從庫表建立、連接配置、頁面編碼到客戶端驗證的完整解決方案。
| 變量 | 含義 | 預設值 |
| character_set_client | 客戶端發送編碼 | latin1 |
| character_set_connection | 連接層轉換編碼 | latin1 |
| character_set_database | 庫預設編碼 | latin1 |
| character_set_results | 結果集返回編碼 | latin1 |
| character_set_server | 服務端預設編碼 | latin1 |
解決方案:三步走
步驟 1:建庫建表指定 UTF-8
CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE mydb;
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50)
) DEFAULT CHARSET=utf8mb4;
推薦 utf8mb4:支援 Emoji 與完整 Unicode,utf8 僅支援 BMP 平面(3 字節)。
步驟 2:PHP 連接後立即執行 SET NAMES
$db_host = "localhost";
$db_user = "root";
$db_pass = "password";
$db_name = "mydb";
$link = mysql_connect($db_host, $db_user, $db_pass);
// 關鍵:設置連接層編碼
mysql_query("SET NAMES 'utf8mb4'", $link);
$db = mysql_select_db($db_name, $link);
$query = "SELECT * FROM users";
$result = mysql_query($query);
SET NAMES 等效於四條命令
SET character_set_client = utf8mb4;
SET character_set_results = utf8mb4;
SET character_set_connection = utf8mb4;
SET collation_connection = utf8mb4_general_ci;
步驟 3:頁面輸出聲明 UTF-8
<meta charset="utf-8">
header("Content-Type: text/html; charset=utf-8");
完整驗證流程
- 資料庫/表/欄位均為 utf8mb4
- PHP 連接執行
SET NAMES utf8mb4
- 頁面 ``
- PHP 源文件以 **UTF-8 無 BOM** 編碼保存(記事本另存為 → 編碼選 UTF-8)
- 插入中文 → 查詢 → 頁面正常顯示
常見場景對應方案
| 場景 | 現象 | 解決 |
| 存入 ???? | 連接層編碼錯誤 | SET NAMES utf8mb4 |
| 讀出 亂碼 | 結果集編碼 ≠ 頁面編碼 | 統一 SET NAMES + 頁面 charset |
| 存入 讀出均正常,但 phpMyAdmin 顯示亂碼 | phpMyAdmin 配置編碼不同 | phpMyAdmin 配置 $cfg['DefaultCharset'] = 'utf-8' |
| 命令行客戶端顯示亂碼 | 終端編碼 ≠ 連接編碼 | mysql> SET NAMES gbk; (Windows cmd) 或 SET NAMES utf8; |
進階:永久配置避免每次 SET NAMES
修改 my.cnf(服務端)
[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
重啟 MySQL 後,新連接自動使用 utf8mb4,無需應用層執行 SET NAMES。
PDO 方式(推薦現代項目)
$dsn = "mysql:host=localhost;dbname=mydb;charset=utf8mb4";
$pdo = new PDO($dsn, $db_user, $db_pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]);
總結檢查清單
- [ ] 安裝 MySQL 選擇 utf8mb4
- [ ] 建庫建表指定 CHARSET=utf8mb4
- [ ] PHP 連接執行 SET NAMES utf8mb4(或配置 my.cnf/pdo)
- [ ] HTML 頁面 ``
- [ ] PHP 文件以 UTF-8 無 BOM 保存
- [ ] 終端/IDE 編碼設置為 UTF-8
徹底解決中文亂碼的核心是:**全鏈路編碼一致性**。從存儲、傳輸、解析到顯示,任何一環不匹配都會導致亂碼。建立標準化配置流程,一次配置,永久受益。
- 上一篇文章: MySQL 核心操作實戰匯總:從建表到備份恢復
- 下一篇文章: SQL 分組取每組前 N 行:Top-N 查詢多種寫法與效能對比
Copyright ©
程式碼之家 All Rights Reserved