PDA

查看完整版本 : mb_string 字元編碼偵測轉換


Tony
2008-08-18, 11:45 AM
除了 iconv, mb_string 也是一個用來轉換偵測字元編碼的好東西。先前再做信件編碼處理的部份, 都是用到 iconv, 不過這次用 mb_string 處理一些簡體、繁體及UTF-8之間的轉換, 所以來寫一下 memo。(基本上只對簡體繁體及UTF-8做處理)
偵測字元編碼我用下面這一段
function detectCharset($str){
$encoding_list = 'ASCII, EUC-CN, BIG-5, UTF-8';
return mb_detect_encoding($str, $encoding_list);
}
嗯~ 看到 $encoding_list , EUC-CN 是..?? 嗯, 在 mb_string 中 EUC-CN 代表的就是 GB2312, 而平常在打的 big5 在 mb_string 則是要成 BIG-5, 就是要多一個 dash ( - ), 跟一般用的編碼名稱稍微有些不一樣, 這裡列出部分 mb_string 的 encoding 名稱:
UTF-8
EUC-JP
ISO-2022-JP
EUC-CN
CP936
BIG-5
在這個列表上怎麼沒看到 GB2312 跟 GBK, 其實, GB2312 就是先前提到的 EUC-CN, 而 GBK 就是 CP936。
在繁簡中文以及UTF-8的偵測的時候, 要注意 $encoding_list 的順序, 如果將 $encoding_list 變成下列的順序位置, 那麼結果可能不會是你想要的。
$encoding_list = 'BIG-5, UTF-8, EUC-CN';
如果用這個 encoding_list 來偵測 GB2312 的字元的時候, 所得到的結果將會是 BIG-5。我想這個結果可能是因為, BIG-5 也包含了一些簡體字元, 不過我測試過的數量不多, 也許會有例外, 但目前這個 encoding_list 的順序還不錯, 可以正確抓到我要的結果。
至於在轉換部份, 看下面這個:
function convertCharset($str, $encoding){
if ($encoding == 'EUC-CN') $encoding = 'CP936';
if ($encoding == 'UTF-8' || $encoding == 'ASCII')
return $str;
else
return mb_convert_encoding($str, 'UTF-8', $encoding);
}

這樣就可以把字串轉成 UTF-8 的編碼啦! 而先前使用 iconv 轉 GB2312 到 UTF-8 的時後, 碰到某些字元會有斷字的現象, 後來乾脆先轉成 GBK, 再轉為 UTF-8, 這樣就解決了文字被截斷的現象了, 即使在 mb_string 裡還是會有類似的狀況, 所以我還是先轉 GBK 再說, 畢竟 GBK 向下相容, 擴充的字元也較多, 例如: 我打’小海’的時候, GB2312 轉成 UTF-8 之後, “海”這個就會亂掉, 而 GBK 就沒這個問題, 只是”海”會變成”烸”, anyway, 我測試的方式是直接打字(用新注音)進 GB2312 的頁面, 但是不管如何, GBK 總是比較沒問題。