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("【囧男孩】為什麼你要一直笑呢?");
?>