php的 iconv 繁簡轉換文字不出來問題解法
tjm | 10 十月, 2008, 13:07 | 技術小抄 | (113 Reads)

php的iconv是個非常好用的函數,可以輕易達成繁簡體轉碼的功能, 但是這個函數有個缺點,當我們輸入「【囧男孩】為什麼你要一直笑呢?」這段字,由於 「囧」這個字不是gb2312支援的字,結果整個輸出會變成「【」,後面的字串全部會消失,而且 php端沒有任何錯誤信息(return也不會變成 false)。

為了解決這個問題,我用了轉回來的字串長度作為檢驗標竿,看看轉回來的字串是否正確,如果不正確,就用二分逼近法,先把正確的部份轉出來,把不正確的部份用遞迴方式繼續切割下去轉,最後把那個造成問題的字換成「?」,這樣就解決了問題。

 <?php
function trangb($str)
 {
        $nstr=iconv('utf-8','big5',$str);
        if (iconv_strlen($str,'utf-8')!=iconv_strlen($nstr,'big5'))
                $nstr=riconv('utf-8','big5',$str);
        $pnstr=iconv('big5','gb2312',$nstr);
        if (iconv_strlen($nstr,'big5')!=iconv_strlen($pnstr,'gb2312'))
                $pnstr=riconv('big5','gb2312',$nstr);
        $nstr= iconv('gb2312','utf-8',$pnstr);
        return $nstr;
 }
function riconv($loc1,$loc2,$str)
{
    $i=iconv_strlen($str,$loc1);
    if ($i<=1)
        return '?';
    $blen=(int)($i/2);
    $elen=$i-$blen;
    $bstr=iconv_substr($str,0,$blen,$loc1);
    $nbstr=iconv($loc1,$loc2,$bstr);
    if (iconv_strlen($bstr,$loc1)!=iconv_strlen($nbstr,$loc2))
        $nbstr=riconv($loc1,$loc2,$bstr);
    $estr=iconv_substr($str,$blen,$elen,$loc1);
    $nestr=iconv($loc1,$loc2,$estr);
    if (iconv_strlen($estr,$loc1)!=iconv_strlen($nestr,$loc2))
        $nestr=riconv($loc1,$loc2,$estr);
    return $nbstr.$nestr;
}
echo trangb("【囧男孩】為什麼你要一直笑呢?");
?>

Trackback URL: http://blog.fhl.net/trackback.php?id=211