前言
PHP 專案遷移或整合舊系統時,常遇到編碼不符導致亂碼。PHP 提供兩大編碼轉換利器:mb_convert_encoding (需 mbstring) 與 iconv (需 iconv)。本文詳細比較兩者差異、安裝方式、常見陷阱與最佳實務。
擴充套件安裝 (以 PHP 5.3 為例,新版本類似)
mbstring
cd /path/to/php-source/ext/mbstring
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install
# 編輯 php.ini
extension=mbstring.so
iconv
cd /path/to/php-source/ext/iconv
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config --with-iconv=/usr/local
make && make install
# 編輯 php.ini
extension=iconv.so
函數簽名與核心差異
| 特性 | mb_convert_encoding | iconv |
| 函數簽名 | string mb_convert_encoding(string $str, string $to_encoding [, mixed $from_encoding = mb_internal_encoding()]) | string iconv(string $in_charset, string $out_charset, string $str) |
| 自動偵測來源編碼 | 支援陣列/清單自動偵測 | 不支援,必須指定 |
| 錯誤處理 | 預設替換字元 | 預設截斷,可加 //IGNORE 忽略、//TRANSLIT 近似替換 |
| 效能 | 較慢 (功能較豐富) | 較快 (C 底層實作) |
| 支援編碼列表 | mb_list_encodings() | iconv -l (系統指令) |
iconv 進階參數://IGNORE 與 //TRANSLIT
$text = "測試 — 特殊字元";
// 忽略無法轉換字元
$gbk = iconv("UTF-8", "GBK//IGNORE", $text);
// 嘗試近似替換 (如 — → --)
$gbk = iconv("UTF-8", "GBK//TRANSLIT", $text);
常見亂碼場景與解決方案
場景 1:GB2312 → UTF-8 遇到特殊字元 (—、•、) 截斷
// 錯誤寫法:GB2312 不支援這些字元
$utf8 = iconv("GB2312", "UTF-8", $text); // 可能截斷或報錯
// 正確寫法:使用 GBK (GB2312 超集)
$utf8 = iconv("GBK", "UTF-8", $text); // 正常轉換
// 或加上 //IGNORE
$utf8 = iconv("GB2312", "UTF-8//IGNORE", $text);
場景 2:來源編碼未知
// mb_convert_encoding 可嘗試多種編碼
$utf8 = mb_convert_encoding($str, "UTF-8", ["GBK", "GB2312", "BIG5", "UTF-8"]);
場景 3:雙重保險 (先 iconv 再 mbstring)
$content = iconv("GBK", "UTF-8", $content); // 快速轉換
$content = mb_convert_encoding($content, "UTF-8", "GBK"); // 修正殘留問題
相關多位元組字串函數補充
| 函數 | 說明 |
mb_strtolower() | 多位元組安全轉小寫 |
mb_strtoupper() | 多位元組安全轉大寫 |
mb_strlen() | 取得字元長度 (非位元組數) |
mb_substr() | 多位元組安全截取 |
mb_strpos() | 多位元組安全搜尋位置 |
最佳實務建議
- 專案統一使用 UTF-8:資料庫、HTML、PHP 檔案、連線編碼全部 UTF-8,避免轉換。
- 輸入端統一轉碼:在 Controller 進入點統一將請求資料轉為 UTF-8。
- 優先使用 iconv:效能較好,搭配
//IGNORE 處理髒資料。
- 來源編碼不確定時:改用
mb_convert_encoding 自動偵測。
- Composer 專案:可考慮
symfony/polyfill-mbstring、symfony/polyfill-iconv 在無擴充套件環境相容。