`
able0001
  • 浏览: 28202 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

[转]PHP程序中的汉字编码探讨

 
阅读更多

最近在做一个百度词典的采集,http://dict.baidu.com,发现了一个可以值得探讨的一个问题,汉字的编码问题。首先,我们输入一个汉字词语进行搜索,比如,我们,URL上的地址变成http://dict.baidu.com/s?wd=%CE%D2%C3%C7,前面的http://dict.baidu.com/s?wd=就不用管了,都知道是什么意思,我们关注一下后面“%CE%D2%C3%C7”这几个东西。显然是词语“我们”这个的汉字编码。我们知道PHP有个函数urlencode,可以把汉字转换为类似那样行事的。,得到结果为:%E6%88%91%E4%BB%AC。

显然,不是%CE%D2%C3%C7这种格式的。是不是进制的问题呢?还是汉字编码的问题(UTF-8或者GB2312)。我们做一下实验。

我们先进行转码:

1
2
3
4
5
6
7
<?php
    $str = '我们';
    //iconv('utf-8','cp936',$str);
    //echo urlencode($str);
    iconv('cp936','utf-8',$str);
    echo urlencode($str);
?>

发现输出结果都为:%E6%88%91%E4%BB%AC,因为我测试的页面为utf-8的页面。所以结果一样。当页面为GBK或者GB2312的时候结果为:%CE%D2%C3%C7,这样,就和百度上的那个编码一致了。现在我们主要讨论页面编码为UTF8的时候,怎么得到正确的编码。
汉字的编码究竟是如何做的。我们知道,国内大部分都是GBK编码的,我们知道,GBK编码中一个汉字由二个字符组成,获取汉字字符串的方法如下:

1
2
3
4
5
6
7
8
9
10
11
<?php
    $string = "我们"; 
    $length = strlen($string); 
    for($i=0;$i<$length;$i++){ 
        if(ord($string[$i])>127){ 
        $result[] =  ord($string[$i]).' '.ord($string[++$i]); 
    } 
    } 
    var_dump($result); 
    
?>

由于一个汉字为两个字符组成,通过ord()函数获取字符的ASCII值如果大于127时,就可以确定当前字符为一个汉字的前半部分,还需要获取汉字的后半部分。当然,这种判断的方法要结合具体的开发环境,如果存在ASCII值大于127的单个字符,这种方法判断显然就不正确。得到结果为一个数组:
GBK编码的页面结果:

1
2
3
4
5
6
array(2) {
  [0]=>
  string(7) "206 210"
  [1]=>
  string(7) "195 199"
}

UTF-8的页面结果:

1
2
3
4
5
6
7
8
array(3) {
  [0]=>
  string(7) "230 136"
  [1]=>
  string(7) "145 228"
  [2]=>
  string(7) "187 172"
}

GB2312的页面结果:

1
2
3
4
5
6
array(2) {
  [0]=>
  string(7) "206 210"
  [1]=>
  string(7) "195 199"
}

从以上结果可以看出,如果页面编码为国标编码的时候,一个汉字是由两个字节组成。而页面编码为UTF8的时候,汉字是由三个字节组成的。但是进制都是十进制的,而我们需要的是十六进制的。那么怎么把十进制的汉字编码转换为十六进制呢?
可以采用以下办法,php由几个内建函数可以直接转换进制,decbin(),十进制转换为二进制;dechex(),十进制转换为十六进制;decoct(), 十进制转换为八进制。

1
2
3
4
5
6
7
<?php 
foreach($result as $v){ 
    $dec = explode(" ",$v); 
    $strings[] =  dechex($dec[0])." ".dechex($dec[1]); 
} 
var_dump($strings); 
?>

UTF8下得到结果为:

1
2
3
4
5
6
7
8
array(3) {
  [0]=>
  string(5) "e6 88"
  [1]=>
  string(5) "91 e4"
  [2]=>
  string(5) "bb ac"
}

看到没,成了十六进制了,同理,转换二进制或者八进制只需将dechex函数换成decbin或者decoct就可以了。
现在我们明白汉字编码和转换进制问题了。

接着我们的问题继续,在UTF8页面上实现转换UTF8汉字为十六进制的GBK汉字编码。
首先学习两个函数:strtoupper() 函数把字符串转换为大写;base_convert() 函数在任意进制之间转换数字;iconv() 函数,实现各种字符集间的转换。mb_detect_encoding() 函数,判断汉字编码。

以上是分步进行转换,先得到汉字编码的十进制编码,然后我们用进制转换函数得到我们想要的汉字编码。下面我们依然这样做。
因为我们的页面是UTF8的页面。所以,我们先得到汉字的十进制编码,当然是UTF8下的编码,然后转成UTF8的十六进制编码。然后使用iconv函数进行字符集转换就了。废话少说,看代码:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
function convertStr($str) {
    $strlength = strlen($str);
    $cstr = '';
    for($i = 0; $i < $strlength; $i++) {
        $cstr .= "%".strtoupper(base_convert(ord($str{$i}), 10, 16));
    }
    return $cstr;
}
$contents = ($contentscharset = mb_detect_encoding($s, "ASCII, UTF-8, GB2312, GBK")) == "GB2312" ? $s : iconv($contentscharset, "CP936", $s);
$w = convertStr($contents);
?>



现在$w就是我们想要的十进制GBK下的汉字编码了了。
convertStr()函数,把汉字以16进制输出。首先判断汉字编码如果是UTF8则由UTF8转换成GBK的。然后执行convertStr()函数,完成进制转换。得到结果为:%CE%D2%C3%C7,这样,我们就得到了这个UTF8下的GBK汉字编码了。

 

<?php
//测试时文件的编码方式要是UTF8
$str='中文a字1符';
echo strlen($str).'<br>';//14
echo mb_strlen($str,'utf8').'<br>';//6
echo mb_strlen($str,'gbk').'<br>';//8
echo mb_strlen($str,'gb2312').'<br>';//10
/*
结果分析:在strlen计算时,对待一个UTF8的中文字符是3个长度,所以“中文a字1符”长度是3*4+2=14
在mb_strlen计算时,选定内码为UTF8,则会将一个中文字符当作长度1来计算,所以“中文a字1符”长度是6 
*/
//利用这两个函数则可以联合计算出一个中英文混排的串的占位是多少(一个中文字符的占位是2,英文字符是1)
echo (strlen($str) + mb_strlen($str,'UTF8')) / 2; 
//例如 “中文a字1符” 的strlen($str)值是14,mb_strlen($str)值是6,则可以计算出“中文a字1符”的占位是10. 
echo mb_internal_encoding();


PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得 到的只是字符串所占的字节数。对于GB2312的中文编码,strlen得到的值是汉字个数的2倍,而对于UTF-8编码的中文,就是3倍的差异了(在 UTF-8编码下,一个汉字占3个字节)。

采用mb_strlen函数可以较好地解决这个问题。mb_strlen的用法和 strlen类似,只不过它有第二个可选参数用于指定字符编码。例如得到UTF-8的字符串$str长度,可以用 mb_strlen($str,'UTF-8')。如果省略第二个参数,则会使用PHP的内部编码。内部编码可以通过 mb_internal_encoding()函数得到。需要注意的是,mb_strlen并不是PHP核心函数,使用前需要确保在php.ini中加载 了php_mbstring.dll,即确保“extension=php_mbstring.dll”这一行存在并且没有被注释掉,否则会出现未定义函 数的问题。

 

分享到:
评论

相关推荐

    php支持生僻字的汉字转拼音类.zip

    本文将深入探讨标题为“php支持生僻字的汉字转拼音类.zip”的压缩包文件,它包含了一个专门处理汉字转拼音的PHP类库,尤其针对生僻字的支持,这对于开发具有汉字转拼音功能的应用或网站来说非常实用。 汉字转拼音是...

    php汉字转拼音类

    在PHP中实现这一功能,通常需要处理汉字到拼音的映射,这涉及到大量的数据处理和编码转换。 类库的实现方式通常包括预处理汉字到拼音的映射表,该表包含所有可能的汉字及其对应的拼音。当需要转化汉字时,程序会...

    使用PHP实现汉字转拼音1

    在本文中,我们将探讨如何使用PHP实现汉字转拼音的功能。这个过程涉及到编码转换、拼音库的使用以及字符串处理等技术。首先,我们需要一个开发环境,这里使用的是Windows 7操作系统,搭配Apache 2.4.18服务器、MySQL...

    PHP中文汉字转拼音程序

    “其它类别”标签表明这个PHP程序可能不仅仅局限于特定的应用场景,它可以被灵活地应用到各种项目中,根据具体需求进行定制和扩展。而“okbase.net”可能是提供的源码库或者服务的域名,暗示了该程序可能来自于一个...

    基于PHP的汉字转拼音工具.zip

    本文将深入探讨基于PHP的汉字转拼音工具及其工作原理、应用场景和实现方法。 汉字转拼音,即通过特定的算法将汉字转换为其对应的汉语拼音,这对于非中文环境下的程序处理汉字信息、搜索引擎优化(SEO)以及语音合成...

    php 跑马灯程序

    4. **GBK编码与字符转换**:在描述中提到了数据库为GBK编码,GBK是中国大陆广泛使用的汉字编码标准,兼容GB2312。如果在UTF-8环境下出现乱码,需要进行编码转换。`Z-Convert`软件是一个常用的字符编码转换工具,可以...

    PHP MySQL程序开发中的乱码产生原因及解决方案分析.pdf

    在PHP和MySQL程序开发中,中文乱码是一个常见的问题,主要由于字符编码的不一致或者处理不当引起。本文将深入探讨这一问题的原因以及相应的解决方案。 首先,我们需要了解字符编码的基本概念。ASCII码是最基础的...

    PHP汉字拼音对照搜索模块,附汉字拼音TXT库

    2. **拼音查询**:当用户输入汉字时,使用PHP的内置函数如iconv或mb_convert_encoding将汉字转为UTF-8编码,然后在拼音库中查找对应的拼音。如果库中存储的是多音字,可能需要考虑多种拼音的情况。 3. **搜索匹配**...

    PHP MYSQL 查询汉字jsonencode处理

    在PHP和MySQL的世界里,处理汉字显示问题是一个常见的挑战,特别是在数据交互和JSON编码过程中。本文将深入探讨如何使用`json_encode`函数解决PHP从MySQL查询后汉字显示异常的问题。 首先,我们需要理解PHP的`json_...

    PHP实例开发源码—LSV蓝海豚PHP开源购物导航程序GBK.zip

    该程序的"GBK"编码意味着它是针对中文环境设计的,GBK是GB2312的扩展,涵盖了更多的汉字,确保了在处理中文字符时的正确性。在处理多语言或中文网站时,理解字符编码是非常重要的,因为它关系到数据的正确显示和存储...

    基于PHP的Wind 社区程序源码 正式GBK build.zip

    GBK是中国大陆广泛使用的汉字编码标准,兼容GB2312,能够表示大部分中文字符。在Wind社区程序中使用GBK编码,确保了对中文字符的良好支持,避免了乱码问题,尤其对于早期的浏览器和系统更为友好。 4. **数据库管理...

    PHP常用函数之获取汉字首字母功能示例

    我们将通过实例来理解相关操作,包括汉字编码转换、截取和计算等技巧。 首先,我们要了解的是汉字的编码方式。在PHP中,汉字通常以UTF-8编码存储,而在某些情况下可能需要转换为其他编码,如GBK。这是因为不同的...

    GBK-BIG5互转.rar

    本文将深入探讨GBK与BIG5编码系统,并基于易语言介绍其互转的实现方法。 GBK,全称为“汉字内码扩展规范”,是在GB2312的基础上发展起来的,涵盖了中国大陆大部分汉字以及部分少数民族文字,共计20902个汉字。GBK...

    史上最全的PHP+MySql中文乱码解决方案文.pdf

    PHP和MySQL中文乱码问题是一个常见的困扰,尤其是在处理多语言网站或者有中文数据输入的应用程序中。乱码的出现通常是由于编码不一致所导致的。本文将深入探讨PHP与MySQL在处理中文字符时可能出现的乱码问题,并提供...

    c# 调用php webservice 源代码

    本文将深入探讨如何在C#环境中调用PHP编写的WebService,并解决可能出现的汉字乱码问题。 首先,让我们理解什么是WebService。WebService是一种基于网络的、独立于平台的应用程序接口(API),它允许不同系统之间...

    php文字水印,支持自动换行

    5. **`index.php`**:作为主入口文件,`index.php`很可能是实现这个功能的应用程序核心,它可能包含用户接口、上传图片的逻辑以及调用`image.class.php`中的方法来添加水印并展示结果。 总结来说,实现"php文字水印...

    PHP程序设计-3期(KC016) 2.8.1字符串长度 常见问题.docx

    在PHP程序设计中,字符串处理是一项基础且重要的任务。本文将深入探讨在处理字符串长度时可能会遇到的问题,尤其是针对初学者常犯的错误。在PHP中,有两个主要的函数用于获取字符串长度:`strlen()` 和 `mb_strlen()...

    PHP随机验证码含有5种样式

    本篇文章将深入探讨PHP实现的五种不同类型的验证码,包括中文、英文以及数字验证码。 首先,我们来了解一下验证码的基本原理。验证码通常由一串随机生成的字符组成,这些字符可能是字母、数字,或者是特定的图形。...

    huoxingwen.rar_huoxingw_php 源码_php 火星语_火星文_火星源码

    这样的PHP程序不仅可以用于娱乐,还可以在特定场景下提供安全的加密功能,例如在论坛或聊天室中保护用户的隐私信息。 总的来说,PHP生成火星文程序源码的实现涉及到字符串处理、随机数生成以及数据查找等多个环节。...

    I18N-ascii

    本文将深入探讨如何在PHP中实现汉字到拼音的转换,这在开发面向多语言用户的应用程序时尤为关键。 #### 概念理解:国际化(I18N) I18N是“国际化”(Internationalization)的简称,代表在产品设计、开发和文档编写...

Global site tag (gtag.js) - Google Analytics