需求背景
處理多來源資料(表單提交、API 回應、檔案匯入)時,編碼常不一致(UTF-8、GBK、BIG5 等)。手動指定編碼易出錯,需一個能自動偵測來源編碼並統一轉換為目標編碼的通用函數。
核心實作:array_iconv 函數
<?php
/**
* 字串/陣列編碼自動偵測與轉換
*
* @param string|array $data 輸入資料(字串或多維陣列)
* @param string $output 目標編碼(預設 UTF-8)
* @return string|array 轉換後的資料
*/
function array_iconv($data, $output = 'UTF-8') {
// 常見編碼偵測順序(越前面優先度越高)
$encodeList = [
'UTF-8', 'ASCII',
'GBK', 'GB2312', 'BIG5', // 中文常用
'JIS', 'EUC-JP', 'SJIS', // 日文常用
'EUC-KR' // 韓文
];
// 遞迴處理陣列
if (is_array($data)) {
foreach ($data as $key => $val) {
// 鍵名也需轉換(可選)
$newKey = is_string($key) ? array_iconv($key, $output) : $key;
$data[$newKey] = array_iconv($val, $output);
if ($newKey !== $key) unset($data[$key]);
}
return $data;
}
// 字串處理
if (is_string($data)) {
$detected = mb_detect_encoding($data, $encodeList, true);
if ($detected && strtoupper($detected) !== strtoupper($output)) {
return mb_convert_encoding($data, $output, $detected);
}
// 已是目標編碼或偵測失敗,直接返回
return $data;
}
// 非字串/陣列(數值、布林、null 等)直接返回
return $data;
}
使用範例
<?php
// 測試資料:混合編碼
$gbkStr = mb_convert_encoding('測試中文', 'GBK', 'UTF-8');
$big5Str = mb_convert_encoding('繁體中文', 'BIG5', 'UTF-8');
$input = [
'utf8' => 'UTF-8 字串',
'gbk' => $gbkStr,
'big5' => $big5Str,
'nested' => [
'item1' => $gbkStr,
'item2' => '另一個 UTF-8',
],
'number' => 123,
'bool' => true,
];
// 統一轉為 UTF-8
$result = array_iconv($input, 'UTF-8');
print_r($result);
/*
Array
(
[utf8] => UTF-8 字串
[gbk] => 測試中文
[big5] => 繁體中文
[nested] => Array
(
[item1] => 測試中文
[item2] => 另一個 UTF-8
)
[number] => 123
[bool] => 1
)
*/
進階版:支援指定來源編碼(提升效能)
function array_iconv_advanced($data, $output = 'UTF-8', $fromEncoding = null) {
// 若指定來源編碼,直接轉換,不偵測
if ($fromEncoding && is_string($data)) {
return mb_convert_encoding($data, $output, $fromEncoding);
}
// 否則走自動偵測邏輯...
return array_iconv($data, $output);
}
關鍵函數說明
| 函數 | 用途 |
mb_detect_encoding() | 依指定清單順序偵測字串編碼,strict=true 避免誤判 |
mb_convert_encoding() | 將字串從來源編碼轉換為目標編碼 |
is_array() / is_string() | 型別判斷,支援遞迴處理多維陣列 |
注意事項與最佳實踐
- 啟用 mbstring:PHP 需編譯
--enable-mbstring 或載入 php_mbstring.dll
- 編碼清單順序:將最可能的編碼放前面,提高偵測準確率
- 效能考量:大量資料建議明確指定來源編碼,避免逐字串偵測開銷
- 資料庫層面解決:連線時設定
SET NAMES utf8mb4,從源頭統一編碼
- 檔案讀取:
fopen() 讀取檔案時可指定編碼旗標或事後轉換
常見編碼對照表
| 編碼名稱 | 適用範圍 | PHP 識別名 |
| UTF-8 | 通用、國際化 | UTF-8 |
| GBK / GB2312 | 簡體中文 Windows | GBK, GB2312 |
| BIG5 | 繁體中文 Windows | BIG5, BIG-5 |
| Shift_JIS | 日文 Windows | SJIS, SJIS-win |
| EUC-JP | 日文 Unix/Linux | EUC-JP, eucjp-win |
| EUC-KR | 韓文 | EUC-KR |