整合舊系統、爬蟲資料、使用者上傳檔案時,字串編碼可能為 UTF-8、Big5、GBK、Latin1 等混雜。直接輸出或存入資料庫易產生亂碼。需一個函式自動偵測並統一轉為 UTF-8。
function to_utf8($data) {
if (empty($data)) return $data;
// 偵測編碼(依優先順序)
$encoding = mb_detect_encoding($data, ['UTF-8', 'GBK', 'BIG5', 'LATIN1'], true);
// 若偵測失敗或已是 UTF-8,直接返回
if ($encoding === false || $encoding === 'UTF-8') {
return $data;
}
// 轉換為 UTF-8
return mb_convert_encoding($data, 'UTF-8', $encoding);
}
function to_utf8_deep($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[$key] = to_utf8_deep($value);
}
return $data;
} elseif (is_object($data)) {
foreach ($data as $key => $value) {
$data->$key = to_utf8_deep($value);
}
return $data;
} elseif (is_string($data)) {
return to_utf8($data);
}
return $data;
}
// 單一字串
$str = file_get_contents('gbk_encoded.txt');
$utf8Str = to_utf8($str);
// $_POST 批次轉換
$_POST = to_utf8_deep($_POST);
// 資料庫查詢結果轉換
$results = $db->query('SELECT * FROM old_table')->fetchAll();
$results = to_utf8_deep($results);
php -m | grep mbstring 確認。mb_convert_encoding($str, 'UTF-8', 'GBK')。SET NAMES utf8mb4)或匯入前批次處理,避免每請求執行偵測。str_replace("\xEF\xBB\xBF", '', $data) 移除。| 方案 | 優點 | 缺點 |
|---|---|---|
| mb_detect_encoding + mb_convert_encoding | 原生、無相依、支援主流編碼 | 短字串偵測不可靠 |
| iconv() | 支援更多編碼、可忽略錯誤字元 | 需指定來源編碼、語法較繁瑣 |
| UConverter (intl 擴充) | ICU 庫支援、偵測更精準 | 需安裝 intl 擴充、記憶體較大 |
| 強制指定編碼 | 效能最好、零誤判 | 需確定來源編碼 |