完全转换UTF-8为GB2312的PHP函数(转载)
时间:2010-08-17 来源:yemuda
Nice,用了下面的转化函数,把困扰俺的编码问题给搞定了,感谢~~
=============华丽丽的转载分割线=================
开始是用“$re=iconv("UTF-8","GB2312",$snoopy->results);”将utf8转换成gb2312,结果经 常出错,到了一半就看不到后文了。后来用“$re=iconv("UTF-8","GB2312//IGNORE",$snoopy-> results);”,加上了忽略错误,好了点,可以转换到底了!可是今天又发现,还是有部分网页无法转换。后来仔细研究发现原来iconv只能转换3字 符的utf8码,如果需要全码转换需要另外写函数。
首先需要了解utf8的构成。
基础:
1、单独使用iconv函数只能转换GB2312字符,外文字符无法转换。
2、没有现成的函数可以用。
3、bindec()函数:将二进制格式的“01”字符串转换为十进制数。
4、decbin()函数:将十进制数转换为二进制字符串,如decbin(224)="11100000"。
思路:因为UTF-8分别有1、2、3字节编码,中日韩文都是3字节编码,处理时根据字符编码中首字节大小区分字节数量。
1、如首字节小于128,为ASCII码。
2、128~192,非UTF-8编码,且处理为“&#ord();”。
3、192~224, 双字节UTF-8编码。
4、224~240,三字节编码。
5、240~248,四字节编码。
6、……
7、对于三字节编码的尝试用iconv转换成GB2312。
8、非GB2312的多字节字符,尝试把UTF-8转换成Unicode,再取到Unicode十进制值。
9、可以考虑使用位运算,也可以用bindec()函数。
程序代码:
程序使用:
经过测试,基本上100%可以转换成gbk码了。
=============华丽丽的转载分割线=================
开始是用“$re=iconv("UTF-8","GB2312",$snoopy->results);”将utf8转换成gb2312,结果经 常出错,到了一半就看不到后文了。后来用“$re=iconv("UTF-8","GB2312//IGNORE",$snoopy-> results);”,加上了忽略错误,好了点,可以转换到底了!可是今天又发现,还是有部分网页无法转换。后来仔细研究发现原来iconv只能转换3字 符的utf8码,如果需要全码转换需要另外写函数。
首先需要了解utf8的构成。
基础:
1、单独使用iconv函数只能转换GB2312字符,外文字符无法转换。
2、没有现成的函数可以用。
3、bindec()函数:将二进制格式的“01”字符串转换为十进制数。
4、decbin()函数:将十进制数转换为二进制字符串,如decbin(224)="11100000"。
思路:因为UTF-8分别有1、2、3字节编码,中日韩文都是3字节编码,处理时根据字符编码中首字节大小区分字节数量。
1、如首字节小于128,为ASCII码。
2、128~192,非UTF-8编码,且处理为“&#ord();”。
3、192~224, 双字节UTF-8编码。
4、224~240,三字节编码。
5、240~248,四字节编码。
6、……
7、对于三字节编码的尝试用iconv转换成GB2312。
8、非GB2312的多字节字符,尝试把UTF-8转换成Unicode,再取到Unicode十进制值。
9、可以考虑使用位运算,也可以用bindec()函数。
程序代码:
function GetGB2312String($name) { $tostr = ""; for($i=0;$i<strlen($name);$i++) { $curbin = ord(substr($name,$i,1)); if($curbin < 0x80) { $tostr .= substr($name,$i,1); }elseif($curbin < bindec("11000000")){ $str = substr($name,$i,1); $tostr .= "&#".ord($str).";"; }elseif($curbin < bindec("11100000")){ $str = substr($name,$i,2); $tostr .= "&#".GetUnicodeChar($str).";"; $i += 1; }elseif($curbin < bindec("11110000")){ $str = substr($name,$i,3); $gstr= iconv("UTF-8","GB2312",$str); if(!$gstr) { $tostr .= "&#".GetUnicodeChar($str).";"; }else{ $tostr .= $gstr; } $i += 2; }elseif($curbin < bindec("11111000")){ $str = substr($name,$i,4); $tostr .= "&#".GetUnicodeChar($str).";"; $i += 3; }elseif($curbin < bindec("11111100")){ $str = substr($name,$i,5); $tostr .= "&#".GetUnicodeChar($str).";"; $i += 4; }else{ $str = substr($name,$i,6); $tostr .= "&#".GetUnicodeChar($str).";"; $i += 5; } } return $tostr; }//end function function GetUnicodeChar($str) { $temp = ""; for($i=0;$i<strlen($str);$i++) { $x = decbin(ord(substr($str,$i,1))); if($i == 0) { $s = strlen($str)+1; $temp .= substr($x,$s,8-$s); }else{ $temp .= substr($x,2,6); } } return bindec($temp); }//end function |
程序使用:
$re=GetGB2312String($snoopy->results); |
经过测试,基本上100%可以转换成gbk码了。
相关阅读 更多 +