GD输出汉字的函数的分析


Posted in PHP onOctober 09, 2006

    很早以前找到一个把GB码转化为UTF-8的函数,配合一个GB到UNICODE的对照表(gb2312.txt),用于在GD中输出汉字。后来发现在欲输出的内容中含有西文字符时,会出现混乱。后来找到了修改后的代码,解决了问题。现将两个函数做一对比分析如下。

首先,这是一个UNICODE到UTF-8编码转换的函数,这一部分修改前后没有变化:
function u2utf8($c)
{
for($i=0;$i<count($c);$i++)
$str="";
if ($c < 0x80) {
$str.=$c;
}
else if ($c < 0x800) {
$str.=(0xC0 | $c>>6);
$str.=(0x80 | $c & 0x3F);
}
else if ($c < 0x10000) {
$str.=(0xE0 | $c>>12);
$str.=(0x80 | $c>>6 & 0x3F);
$str.=(0x80 | $c & 0x3F);
}
else if ($c < 0x200000) {
$str.=(0xF0 | $c>>18);
$str.=(0x80 | $c>>12 & 0x3F);
$str.=(0x80 | $c>>6 & 0x3F);
$str.=(0x80 | $c & 0x3F);
}
return $str;
}

这里完全是按照UTF-8编码的规则,通过判断字符属于不同的UNICODE编码段范围,进行不同的移位和位与操作,以转化为UTF-8编码。关于该规则可参考http://www.utf8.org/上的说明。

这是修改前的GB转化为UTF-8编码的函数,其中调用了上面的u2utf8函数。
function gb2utf8($gb)     /* Program writen by sadly www.phpx.com  */
{
if(!trim($gb))
return $gb;
$filename="gb2312.txt";
$tmp=file($filename);
$codetable=array();
while(list($key,$value)=each($tmp))
$codetable[hexdec(substr($value,0,6))]=substr($value,7,6);
$utf8="";
while($gb)
{
if (ord(substr($gb,0,1))>127)
{
$this=substr($gb,0,2);
$gb=substr($gb,2,strlen($gb));
$utf8.=u2utf8(hexdec($codetable[hexdec(bin2hex($this))-0x8080]));
}
else
{
$gb=substr($gb,1,strlen($gb));
$utf8.=u2utf8(substr($gb,0,1));
}
}

$ret="";
for($i=0;$i<strlen($utf8);$i+=3)
$ret.=chr(substr($utf8,$i,3));

return $ret;
}
函数中while循环部分,把汉字逐个按照“对照表”转化为UNICODE,再通过u2utf8函数转化为UTF-8。但从中可以看出,while循环结束后,又用一个for循环,把每三个字节合成了一个UTF-8字符(见http://www.utf8.org/上的规则说明,每个汉字的UTF-8编码为三字节),没有考虑到其中的西文字符(西文字符的UTF-8编码为一字节)。所以,如果欲输出的内容中不论是开始时出现西文字符,或是汉字当中穿插西文字符,转化为UTF-8后,都会被按照“每三个字节截取”的方式截开,导致乱码。

以下是修改后的函数:
function gb2utf8($gb)    /* Program writen by sadly   modified by agun */
{
if(!trim($gb))
return $gb;
$filename="gb2312.txt";
$tmp=file($filename);
$codetable=array();
while(list($key,$value)=each($tmp))
$codetable[hexdec(substr($value,0,6))]=substr($value,7,6);

$ret="";
$utf8="";
while($gb)
{
if (ord(substr($gb,0,1))>127)
{
$this=substr($gb,0,2);
$gb=substr($gb,2,strlen($gb));
$utf8=u2utf8(hexdec($codetable[hexdec(bin2hex($this))-0x8080]));
for($i=0;$i<strlen($utf8);$i+=3)
$ret.=chr(substr($utf8,$i,3));
}
else
{
$ret.=substr($gb,0,1);
$gb=substr($gb,1,strlen($gb));
}
}
return $ret;
}

修改后的函数将 GB转化为UNICODE、UNICODE转化为UTF-8、几个字节合成一个UTF-8字符,这三个步骤在一个循环里完成,尤其是几个字节合成一个UTF-8字符这一步骤,放在判断了字符属于西文还是属于汉字的条件分支里,据此决定截取一个字节还是三个字节。于是结果正确了!

PHP 相关文章推荐
php auth_http类库进行身份效验
Mar 19 PHP
通用PHP动态生成静态HTML网页的代码
Mar 04 PHP
深入掌握include_once与require_once的区别
Jun 17 PHP
PHP $_FILES中error返回值详解
Jan 30 PHP
php输入数据统一类实例
Feb 23 PHP
PHP实现HTTP断点续传的方法
Jun 17 PHP
php实现图片上传、剪切功能
May 07 PHP
PHP 数组基本操作小结(推荐)
Jun 13 PHP
php求数组全排列,元素所有组合的方法总结
Mar 14 PHP
PHP简单实现遍历目录下特定文件的方法小结
May 22 PHP
PHP数组遍历的几种常见方式总结
Feb 15 PHP
PHP的Trait机制原理与用法分析
Oct 18 PHP
类的另类用法--数据的封装
Oct 09 #PHP
最小化数据传输――在客户端存储数据
Oct 09 #PHP
网站加速 PHP 缓冲的免费实现方法
Oct 09 #PHP
Windows下PHP的任意文件执行漏洞
Oct 09 #PHP
通过对服务器端特性的配置加强php的安全
Oct 09 #PHP
用Zend Encode编写开发PHP程序
Oct 09 #PHP
在php中使用sockets:从新闻组中获取文章
Oct 09 #PHP
You might like
PHP 文件类型判断代码
2009/03/13 PHP
理解php原理的opcodes(操作码)
2010/10/26 PHP
phpmyadmin打开很慢的解决方法
2014/04/21 PHP
ThinkPHP模板Switch标签用法示例
2014/06/30 PHP
laravel migrate初学常见错误的解决方法
2017/10/11 PHP
PHP实现的数据对象映射模式详解
2019/03/20 PHP
PHP安全之register_globals的on和off的区别
2020/07/23 PHP
javascript实现的像java、c#之类的sleep暂停的函数代码
2010/03/04 Javascript
判断目标是否是window,document,和拥有tagName的Element的代码
2010/05/31 Javascript
Javascript页面添加到收藏夹的简单方法
2013/08/07 Javascript
JS获取键盘上任意按键的值(实例代码)
2013/11/12 Javascript
jquery获取css中的选择器(实例讲解)
2013/12/02 Javascript
js/jQuery简单实现选项卡功能
2014/01/02 Javascript
JS原型链怎么理解
2016/06/27 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
2017/01/19 Javascript
Jquery uploadify 多余的Get请求(404错误)的解决方法
2017/01/26 Javascript
bootstrap table表格使用方法详解
2017/04/26 Javascript
[js高手之路]原型式继承与寄生式继承详解
2017/08/28 Javascript
基于JavaScript+HTML5 实现打地鼠小游戏逻辑流程图文详解(附完整代码)
2017/11/02 Javascript
vue 设置路由的登录权限的方法
2018/07/03 Javascript
JAVA面试题 static关键字详解
2019/07/16 Javascript
js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结
2020/03/04 Javascript
Python实现字典的key和values的交换
2015/08/04 Python
python机器学习理论与实战(六)支持向量机
2018/01/19 Python
python导出hive数据表的schema实例代码
2018/01/22 Python
Python开发之pip安装及使用方法详解
2020/02/21 Python
浅析css3中matrix函数的使用
2016/06/06 HTML / CSS
HTML5本地存储之Web Storage应用介绍
2013/01/06 HTML / CSS
Maje德国官网:法国女性成衣品牌
2017/02/10 全球购物
如何使用PHP session
2015/04/21 面试题
如何查找网页漏洞
2016/06/22 面试题
大学生职业规划范文:象牙塔生活的四年计划
2014/01/14 职场文书
家具促销活动方案
2014/02/16 职场文书
幼儿园元旦活动感言
2014/03/02 职场文书
邀请函样本
2015/02/02 职场文书
车间班组长竞聘书
2015/09/15 职场文书