不用iconv函数实现UTF-8编码转换GB2312的PHP函数 晴

jed , 2006-10-11 16:08 , 代码编程 , 评论(0) , 阅读(7323) , Via 本站原创 | |
如果使用 iconv() 函数转换编码就相比比较简单了,不过很多虚拟主机里并不支持这个组件,我在网上找半天,才找到一个gb2312转utf-8的方法,但不能逆向转换。

这个函数如下:

/*******************************
//GB转UTF-8编码
*******************************/
function gb2utf8($gbstr) {
global $CODETABLE;
if(trim($gbstr)=="") return $gbstr;
if(empty($CODETABLE)){
 $filename = dirname(__FILE__)."/gb2312-utf8.table";
 $fp = fopen($filename,"r");
 while ($l = fgets($fp,15))
 { $CODETABLE[hexdec(substr($l, 0, 6))] = substr($l, 7, 6); }
 fclose($fp);
}
$ret = "";
$utf8 = "";
while ($gbstr) {
 if (ord(substr($gbstr, 0, 1)) > 127) {
  $thisW = substr($gbstr, 0, 2);
  $gbstr = substr($gbstr, 2, strlen($gbstr));
  $utf8 = "";
  @$utf8 = u2utf8(hexdec($CODETABLE[hexdec(bin2hex($thisW)) - 0x8080]));
  if($utf8!=""){
&nbsp; &nbsp;for ($i = 0;$i < strlen($utf8);$i += 3)
&nbsp; &nbsp; $ret .= chr(substr($utf8, $i, 3));
&nbsp; }
&nbsp;}
&nbsp;else
&nbsp;{
&nbsp; $ret .= substr($gbstr, 0, 1);
&nbsp; $gbstr = substr($gbstr, 1, strlen($gbstr));
&nbsp;}
}
return $ret;
}
//Unicode转utf8
function u2utf8($c) {
for ($i = 0;$i < count($c);$i++)
&nbsp;$str = "";
if ($c < 0x80) {
&nbsp;$str .= $c;
} else if ($c < 0x800) {
&nbsp;$str .= (0xC0 &#124; $c >> 6);
&nbsp;$str .= (0x80 &#124; $c & 0x3F);
} else if ($c < 0x10000) {
&nbsp;$str .= (0xE0 &#124; $c >> 12);
&nbsp;$str .= (0x80 &#124; $c >> 6 & 0x3F);
&nbsp;$str .= (0x80 &#124; $c & 0x3F);
} else if ($c < 0x200000) {
&nbsp;$str .= (0xF0 &#124; $c >> 18);
&nbsp;$str .= (0x80 &#124; $c >> 12 & 0x3F);
&nbsp;$str .= (0x80 &#124; $c >> 6 & 0x3F);
&nbsp;$str .= (0x80 &#124; $c & 0x3F);
}
return $str;
}

因为gb2312都是双字节的,因此转换为utf-8就相对比较简单,但反之有很麻烦了,我尝试了一下:

这样

function utf82gb($utfstr)
{
global $UC2GBTABLE;
$okstr = "";
if(trim($utfstr)=="") return $utfstr;
if(empty($UC2GBTABLE)){
&nbsp;$filename = dirname(__FILE__)."/gb2312-utf8.table";
&nbsp;$fp = fopen($filename,"r");
&nbsp;while($l = fgets($fp,15))
&nbsp;{ $UC2GBTABLE[hexdec(substr($l, 7, 6))] = hexdec(substr($l, 0, 6));}
&nbsp;fclose($fp);
}
$ulen = strlen($utfstr);
for($i=0;$i<$ulen;$i++)
{
&nbsp;if(ord($utfstr[$i])<0x81) $okstr .= $utfstr[$i];
&nbsp;else
&nbsp;{
&nbsp; if($ulen>$i+2)
&nbsp; {
&nbsp; &nbsp;$utfc = substr($utfstr,$i,3);
&nbsp; &nbsp;$c = "";
&nbsp; &nbsp;@$c = dechex($UC2GBTABLE[utf82u_3($utfc)]+0x8080);
&nbsp; &nbsp;if($c!=""){
&nbsp; &nbsp; &nbsp; $okstr .= chr(hexdec($c[0].$c[1])).chr(hexdec($c[2].$c[3]));
&nbsp; &nbsp;}
&nbsp; }
&nbsp; else
&nbsp; { $okstr .= $utfstr[$i]; }
&nbsp;}
&nbsp;}
&nbsp;$okstr = trim($okstr);
&nbsp;return $okstr;
}

function utf82u_3($c)
{
&nbsp; &nbsp; &nbsp;$n = (ord($c[0]) & 0x1f) << 12;
&nbsp; &nbsp; &nbsp;$n += (ord($c[1]) & 0x3f) << 6;
&nbsp; &nbsp; &nbsp;$n += ord($c[2]) & 0x3f;
&nbsp; &nbsp; &nbsp;return $n;
}

按这种方法,大部份字符也算是能转换成功的了,不过总是有点不妥之处,我把程序改成这样子:

function utf82gb($utfstr)
{
global $UC2GBTABLE;
$okstr = "";
if(trim($utfstr)=="") return $utfstr;
if(empty($UC2GBTABLE)){
&nbsp;$filename = dirname(__FILE__)."/gb2312-utf8.table";
&nbsp;$fp = fopen($filename,"r");
&nbsp;while($l = fgets($fp,15))
&nbsp;{ $UC2GBTABLE[hexdec(substr($l, 7, 6))] = hexdec(substr($l, 0, 6));}
&nbsp;fclose($fp);
}
$okstr = "";
$utfstr = urlencode($utfstr);
$ulen = strlen($utfstr);
for($i=0;$i<$ulen;$i++)
{
&nbsp;if($utfstr[$i]=="%")
&nbsp;{
&nbsp; if($ulen>$i+2){
&nbsp; &nbsp;$hexnext = hexdec("0x".substr($utfstr,$i+1,2));
&nbsp; &nbsp;if($hexnext<127){
&nbsp; &nbsp; $okstr .= chr($hexnext);
&nbsp; &nbsp; $i = $i+2;
&nbsp; &nbsp;}
&nbsp; &nbsp;else{
&nbsp; &nbsp; if($ulen>=$i+9){
&nbsp; &nbsp; &nbsp;$hexnext = substr($utfstr,$i+1,8);
&nbsp; &nbsp; &nbsp;$c = "";
&nbsp; &nbsp; &nbsp;@$c = dechex($UC2GBTABLE[url_utf2u($hexnext)]+0x8080);
&nbsp; &nbsp; &nbsp;if($c!=""){
&nbsp; &nbsp; &nbsp; &nbsp;$okstr .= chr(hexdec($c[0].$c[1])).chr(hexdec($c[2].$c[3]));
&nbsp; &nbsp; &nbsp;}
&nbsp; &nbsp; &nbsp;$i = $i+8;
&nbsp; &nbsp; }
&nbsp; &nbsp;}
&nbsp; }
&nbsp; else
&nbsp; { $okstr .= $utfstr[$i]; }
&nbsp;}
&nbsp;else if($utfstr[$i]=="+")
&nbsp; $okstr .= " ";
&nbsp;else
&nbsp; $okstr .= $utfstr[$i];
}
$okstr = trim($okstr);
return $okstr;
}
//三字节的URL编码转成的utf8字符转为unicode编码
function url_utf2u($c)
{
$utfc = "";
$cs = split("%",$c);
for($i=0;$i<count($cs);$i++){
&nbsp;$utfc .= chr(hexdec("0x".$cs[$i]));
}
$n = (ord($utfc[0]) & 0x1f) << 12;
&nbsp;$n += (ord($utfc[1]) & 0x3f) << 6;
&nbsp;$n += ord($utfc[2]) & 0x3f;
return $n;
}

一测试,发现完全OK,而且速度居然比上一个方法要快,我真是搞不懂这是什么原因了

谁要 gb2312-utf8.table 这个文件请加我的QQ 2500875 IT柏拉图 或与 1877000 泡泡 联系
Tags: , ,
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]