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

PHP 字符編碼詳解:ASCII、GB2312、BIG5、GB18030、Unicode、UTF-8 歷史與實踐

     編輯:PHP 綜合知識

中文字符編碼演進史與 PHP 實戰避坑指南

從 ASCII 到 Unicode,中文編碼經歷了單字節擴展、雙字節國標、繁體大五碼、國家擴展標準、統一碼多階段演進。本文系統梳理各編碼技術特徵、適用場景、PHP 中的亂碼根因與解決方案。

編碼演進時間軸

年份標準類型字符集覆蓋關鍵特徵
1963ASCII7-bit128 字符僅英語、控制字符、標點
1981GB2312-80雙字節6763 漢字 + 符號簡體中文國標,區位碼,99.75% 覆蓋率
1984BIG5雙字節13053 繁體字台灣五大廠商聯發,含重碼,缺生僻字
1990+Unicode 1.016-bit/32-bit全球統一碼位學術機構推動,碼位空間巨大
1993UTF-8變長 1-4 字節Unicode 全覆蓋ASCII 兼容、網絡傳輸首選、無字節序問題
2000GB18030-2000單/雙/四字節27484 漢字 + 少數民族國家強制標準、兼容 GB2312、與 Unicode 3.0 映射
2005Unicode 4.1—10 萬+ 字符含 Emoji、歷史字符、擴展區

核心編碼技術對比

ASCII 與擴展 ASCII

  • 標準 ASCII:7 位,0x00-0x7F (0-127)
  • 擴展 ASCII:8 位,0x00-0xFF (0-255),高 128 個廠商自定義 (如 ISO-8859-1、CP437)

GB2312 (CP936 / EUC-CN)

  • 編碼結構:雙字節,高位 0xA1-0xF7 (區號+0xA0),低位 0xA1-0xFE (位號+0xA0)
  • 分區:01-09 區符號,16-55 區一級漢字(拼音序),56-87 區二級漢字(部首筆畫序)
  • 示例:「啊」區位 1601 → 高字節 0xB0(16+0xA0),低字節 0xA1(1+0xA0) → B0 A1

BIG5 (CP950)

  • 高位:0xA1-0xF9,低位:0x40-0x7E、0xA1-0xFE
  • 安排:符號 0xA140-0xA3BF,常用字 0xA440-0xC67E (筆畫序),次常用 0xC940-0xF9D5
  • 缺陷:重碼(兀、嗀)、缺生僻人名字、無日文假名

GB18030 (CP54936)

  • 三模式:單字節(0x00-0x7F 兼容 ASCII)、雙字節(高 0x81-0xFE,低 0x40-0x7E/0x80-0xFE)、四字節(擴展區,前綴 0x30-0x39)
  • 收錄:27484 漢字,含 CJK 擴展 A、少數民族文字、日韓字符
  • 強制性:2001 年後中國市場軟件必須支援

Unicode 與 UTF 族

方案碼位範圍字節長度特點
UTF-8U+0000 - U+10FFFF1-4 字節 (變長)ASCII 兼容、無字節序、網絡標準、MySQL 需用 utf8mb4
UTF-16U+0000 - U+10FFFF2 或 4 字節需 BOM 區分大小端、Java/JS/WinAPI 內部用
UTF-32U+0000 - U+10FFFF固定 4 字節直接索引碼位、佔空間大、內部處理用

PHP 中的編碼亂碼根因與解決層級

層級 1:HTTP 響應頭 (最高優先級)

<?php
// 必須在任何輸出前
header('Content-Type: text/html; charset=UTF-8');
// 或
header('Content-Type: application/json; charset=UTF-8');
覆蓋 HTML meta、Apache 默認字符集、PHP 內部默認字符集。

層級 2:HTML Meta 標簽

<meta charset="UTF-8">
<!-- HTML5 簡寫 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- 兼容寫法 -->

層級 3:Apache 配置

# httpd.conf 或 .htaccess
AddDefaultCharset UTF-8
# 或註釋掉讓 PHP/HTML 控制
# AddDefaultCharset Off

層級 4:PHP 內部默認字符集

; php.ini
default_charset = "UTF-8"
; 影響 htmlentities、htmlspecialchars、json_encode 等默認編碼

層級 5:資料庫連接字符集

<?php
// PDO (推薦)
$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', $user, $pass);

// mysqli
$mysqli->set_charset('utf8mb4');

// 避免使用 SET NAMES (不影響 PDO 內部狀態)

層級 6:文件源碼編碼

  • 編輯器保存為 UTF-8 無 BOM
  • PHP 解析器按文件編碼讀取字符串字面量

優先級順序 (高 → 低)

1. PHP header()           ← 代碼控制,最可靠
2. Apache AddDefaultCharset
3. HTML 
4. PHP default_charset
5. 瀏覽器自動檢測

常見亂碼場景速查表

現象原因解決
中文顯示 UTF-8 頁面被 GBK 解碼統一聲明 UTF-8,檢查 header/meta
中文顯示 鏂伴椈GBK 頁面被 UTF-8 解碼同上
入庫變 ???連接字符集非 utf8mb4PDO DSN 加 charset=utf8mb4
Emoji 存不進/變 ?MySQL utf8 只支援 3 字節表/庫/連接全鏈路 utf8mb4
json_encode 變 \uXXXX默認轉義非 ASCIIJSON_UNESCAPED_UNICODE
curl 獲取亂碼遠程編碼非 UTF-8iconv/mb_convert_encoding 轉碼

PHP 編碼轉換函數速查

<?php
// 多字節字符串轉換 (需 mbstring)
mb_convert_encoding($str, 'UTF-8', 'GBK');  // 指定源編碼
mb_convert_encoding($str, 'UTF-8', 'auto'); // 自動檢測 (不準確)

// iconv (系統級,支援更多編碼)
iconv('GBK', 'UTF-8//IGNORE', $str);  // //IGNORE 忽略非法字符
iconv('UTF-8', 'GBK//TRANSLIT', $str); // //TRANSLIT 近似轉換

// 文件編碼批量轉換 (Linux)
# find . -name "*.php" -exec iconv -f GBK -t UTF-8 {} -o {}.utf8 \;

最佳實踐總結

  1. 全棧 UTF-8:源碼、HTML、HTTP Header、PHP default_charset、資料庫連接、表字符集
  2. MySQL 必須用 utf8mb4:CREATE DATABASE ... CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  3. 入口統一聲明:框架入口文件 header('Content-Type: ...; charset=UTF-8')
  4. 外部數據轉碼:第三方 API、爬蟲、舊系統數據,明確源編碼用 mb_convert_encoding
  5. 避免 BOM:UTF-8 無 BOM,防止輸出前空白導致 header 失效
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved