亂碼產生根因
MySQL 連接涉及字符集協商,當客戶端、連接層、結果集、數據庫存儲四者編碼不一致時,中文會出現亂碼、問號、截斷等問題。
常見解決方案
方案一:SET NAMES(最常用)
方案二:分別設置三個字符集變量(更精確控制)
方案三:mysql_set_charset() 函數(PHP 5.2.3+ 推薦)
字符集選擇指南
| 場景 | 推薦字符集 | SET NAMES 參數 |
| 新項目(推薦) | utf8mb4 | utf8mb4 |
| 舊項目維護(GBK 體系) | gbk | gbk / gb2312 |
| 僅存儲基本中文 | utf8 (utf8mb3) | utf8 |
| 需支持 Emoji/生僻字 | utf8mb4 | utf8mb4 |
完整驗證流程
各層級字符集一致性檢查
-- 1. 數據庫級別
SHOW CREATE DATABASE db_name;
ALTER DATABASE db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
-- 2. 表級別
SHOW CREATE TABLE table_name;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 3. 列級別
SHOW FULL COLUMNS FROM table_name;
ALTER TABLE table_name MODIFY col_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
PHP 文件編碼與輸出編碼
';
// 4. 數據庫連接字符集(三選一)
mysql_set_charset('utf8mb4', $link); // 推薦
// mysql_query("SET NAMES utf8mb4", $link);
遷移到 mysqli / PDO 的對應寫法
| 操作 | mysql (舊) | mysqli | PDO |
| 設置字符集 | mysql_set_charset('utf8', $link) | $mysqli->set_charset('utf8mb4') | DSN: charset=utf8mb4 |
| 查詢字符集 | mysql_query("SHOW VARIABLES...") | $mysqli->character_set_name() | $pdo->query("SHOW VARIABLES...") |
故障排查清單
- [ ] PHP 文件編碼為 UTF-8 without BOM
- [ ] HTTP 響應頭包含 charset=utf-8
- [ ] HTML 頁面有
<meta charset="utf-8">
- [ ] 數據庫/表/列字符集統一為目標編碼
- [ ] 連接建立後立即設置字符集(選擇數據庫前)
- [ ] 使用
mysql_set_charset() 而非手動 SET NAMES
- [ ] 讀寫測試驗證中文完整性