中文亂碼本質是編碼與解碼不一致。各國制定字符集(ASCII、GB2312、JIS),早期本地化版本導致交換困難,Unicode 統一碼位解決此問題。現代軟體核心以 Unicode 運作,I/O 時按 Locale 轉換。Web 環境下,瀏覽器、Web Server、PHP、資料庫四端編碼必須**完全一致**。
CHARSET=utf8mb4(支援 Emoji),COLLATE=utf8mb4_unicode_ci。SET NAMES utf8mb4(或對應頁面編碼)。告知 MySQL:客戶端發送/接收均用此編碼。latin1 (ISO-8859-1) 存中文:需手動拆分雙位元組,極易出錯且廢棄資料庫原生支援。在懷疑點輸出字串**內碼十六進制**:
echo bin2hex($str); // 或 var_dump(unpack('H*', $str));
觀察:何時變 Unicode、何時被截斷、何時變問號、何時高位元丟失。測試樣本建議用 aa啊aa?@aa(中英混雜、含 GB/GBK 特徵字),英文段永遠不變可作基準。
header():header('Content-Type: text/html; charset=utf-8'); 發送 HTTP 標頭,**瀏覽器無條件服從**,最可靠。AddDefaultCharset:httpd.conf 中 AddDefaultCharset utf-8 等同給每檔加 header。註解掉可讓 meta 生效。<meta charset="utf-8">:屬 HTML 內容,優先級較低,若前兩者存在則被忽略。php.ini default_charset:建議註解關閉,讓瀏覽器依網頁標頭自動選擇,支援同站多語系。utf8mb4SET NAMES utf8mb4header('Content-Type: text/html; charset=utf-8'); 在**任何輸出前**呼叫字符集知識是解碼亂碼的地圖,按圖索驄,亂碼無處遁形。