首页 > 开发 > PHP > 正文

技巧文章:UTF8下的中文PHP编程

2024-05-04 23:03:53
字体:
来源:转载
供稿:网友
  • 网站运营seo文章大全
  • 提供全面的站长运营经验及seo技术!
  • 前言:

    说实话,
    凉鞋也觉得 utf8 是好东西……
    毕竟同屏显示中日韩对东亚人的吸引力是不小的……
    (当然好处不仅是这点啦……)
    不仅是网页程式……
    很多应用程式的内核都开始使用 unicode 编码……
    目的是显而易见的:支援多语言显示……
    微软的所有软体都是 unicode 内核……
    所以日文软体拿到你的中文 xp 上是可以正常显示的……
    而中文 98 就会因为 gb 内核安装其他语言软体时造成乱码……

    至于 utf8 ,
    可以说是 unicode 的一个分支,
    它用三个字节保存一个汉字……
    (unicode 用四个字节)
    应用软体都集体投奔 unicode 了……
    就不允许我们搞网页程式的用 utf8?

    本文中凉鞋就尽量多方位介绍一下 utf8 编码下的 php 编程……
    至于为什么单独介绍“中文”……
    一来是因为英文这玩意实在不需要考虑 utf8 ……
    除非你准备做多语言系统……
    (我要发些牢骚:现在的老外写程式时根本不重视这个问题……)
    二来是中日韩等多字节语系在 utf8 编码下的处理方式其实大同小异……
    依葫芦画瓢即可……
    好……先从数据库处理部分开始吧……


    ==========================================
    连接数据库

    很多人刚升级到 mysql 4.1 时会发现数据乱掉了……
    其实是因为 mysql 从 4.1 开始支援字符集了……
    而且默认字符集正是 utf8 ……
    (充分证明与国际接轨的重要性…… 嘿嘿……)
    而以前我们大多使用 utf8 或是 gbk 编码……
    这样以来输出的数据当然是乱码……
    要解决乱码……
    就得让程序知道该获取什么编码的数据……

    我们假设你以前的数据库是 utf8 编码的……
    那么你可以在查询前添加一句

    mysql_query('set character set utf8') or die("query failed : " . mysql_error());
    当然,由于 4.1 以上才需要这样处理,
    因此我们可以加上判断:

    $mysqlversion = $db->query_first("select version() as version");
    if ($mysqlversion['version'] >= '4.1')
    {
    mysql_query('set character set utf8') or die("query failed : " . mysql_error());
    }
    这样以来不管 mysql 默认编码是什么都可以正常存取了……
    (不论您是存活期,还是存定期,甚至是零存整取都没有问题鸟……)

    但是,人家都国际化鸟……
    您还在用 utf8 行么?
    如何转码呢?
    还有……
    数据升级时出现乱码怎么办?
    凉拌!
    且听下回分解……

    ============================================
    数据升级至 4.1

    要升级……
    就得先导出……
    要说老外还真不负责……
    以前的导出方式总是弄丢一些中文字符……
    比如把“我爱你娘”弄成“我爱你”啦……
    (通常是丢失一段数据最末尾的字)
    整个儿差了一辈儿……
    (用石榴姐的话说就是“这么大逆不道的事实在是太刺激了”……)
    为了保护您脆弱的心脏……
    也为了维护中国传统伦理道义……
    您可以把数据包含中文字符的字段改为二进制(binary)编码……
    具体方法嘛……
    可以运行这个语句:

    alter table `表名` convert to character set binary;
    这样,那些字符类型字段,如:
    char、varchar 和 text
    将转换为
    binary、varbinary 和 blob
    然后再导出并导入到 4.1 环境中……
    当然,最后一项繁琐的工作是:
    你需要把它们的类型再改回来……

    有往 4.1 升级的……
    当然也有往下降级的……
    怎么降级???
    凉鞋去上个厕所……
    而您请翻下页……

    =============================================
    数据从 4.1 降级

    有人发现从4.1导出的 sql 文件无法导入低版本程序……
    问题其实很简单……
    而且 mysql 已经为我们想好了一切……
    导出时请添加 –compatible 参数……
    我们假设您的数据库是 utf8 编码的……
    而且目标数据库版本为 4.0 ……
    那么命令行下这么写:

    shell>mysqldump --user=username --password=password --compatible=mysql40 --default-character-set=utf8 database > db.sql
    这样导出的 sql 文件就能够顺利导入低版本数据库了……

    数据库部分算是搞定了……
    但 php 编程方面要如何注意呢?
    还得劳您翻下页……
    http://www.knowsky.com
    =============================================
    php 文件编码

    是否所有 php 文件都必须转成 utf8 编码呢?
    凉鞋告诉您是 no ……

    这么说吧……
    如果文件中包含需要显示出来的中文字符……
    就应该转为 utf8 编码……
    举例子吧:

    // 我是凉鞋
    echo time();
    上面的代码虽有代码……
    但是由于存在于注释中……
    不会输出……
    所以这个页面可以不用转换为 utf8 格式……

    再如:

    echo "我是凉鞋";
    这个明显有中文字符输出……
    您还是老老实实转换为 utf8 吧……

    当然现在很多程式都采用模板(语言包)技术……
    程式(非语言包文件)里是看不到任何供输出的字符的……
    这样以来我们只需要将语言包文件转成 utf8 编码即可……
    (语言包的优势就在这里啊…… 啊哈哈哈哈哈……)
    'http://www.knowsky.com
    ==================================================

    utf8 中文截取

    由于 utf8 使用三个字节……
    所以传统的 substr 函数就没辙了……
    很多高手都写了 utf8 中文字符截取函数……
    这里送上几种:

    1.先算再取

    /**
    * author : dummy | zandy
    * email : [email protected] | hotmail.com
    * create : 200512
    * usage : echo join('', string::substring_utf8('汉字', 0, 1));
    */
    ini_set('display_errors', 1);
    error_reporting(e_all ^ e_notice);
    class string {
    function substring_utf8($str, $start, $lenth)
    {
    $len = strlen($str);
    $r = array();
    $n = 0;
    $m = 0;
    for($i = 0; $i < $len; $i++) {
    $x = substr($str, $i, 1);
    $a = base_convert(ord($x), 10, 2);
    $a = substr('00000000'.$a, -8);
    if ($n < $start){
    if (substr($a, 0, 1) == 0) {
    }elseif (substr($a, 0, 3) == 110) {
    $i += 1;
    }elseif (substr($a, 0, 4) == 1110) {
    $i += 2;
    }
    $n++;
    }else{
    if (substr($a, 0, 1) == 0) {
    $r[] = substr($str, $i, 1);
    }elseif (substr($a, 0, 3) == 110) {
    $r[] = substr($str, $i, 2);
    $i += 1;
    }elseif (substr($a, 0, 4) == 1110) {
    $r[] = substr($str, $i, 3);
    $i += 2;
    }else{
    $r[] = '';
    }
    if (++$m >= $lenth){
    break;
    }
    }
    }
    return $r;
    } // end substring_utf8
    }// end string
    echo join('', string::substring_utf8('汉字', 0, 1));
    2.先截后取
    这种方式凉鞋觉得很巧妙……
    用传统截取函数先截断……
    然后判断中文单个字符是否被分割开……
    如果是……则处理之……
    要特别注意的是 substr 函数的第三个参数必须大于 3 ……
    至于为什么不用凉鞋解释了吧?

    // a trim function to remove the last character of a utf-8 string
    // by following instructions on http://en.wikipedia.org/wiki/utf-8
    // dotann
    // usage: $str = utf8_trim(substr($str,0,50));
    function utf8_trim($str) {
    $len = strlen($str);
    for ($i=strlen($str)-1; $i>=0; $i-=1){
    $hex .= ' '.ord($str[$i]);
    $ch = ord($str[$i]);
    if (($ch & 128)==0) return(substr($str,0,$i));
    if (($ch & 192)==192) return(substr($str,0,$i));
    }
    return($str.$hex);
    }
    $str = '汉字';
    echo utf8_trim(substr($str,0,3));
    3.还有其它方法,
    比如 007pig 为我们 vbulletin 中文版里所写的函数……
    短小精悍……
    源码不便放出……
    对不住鸟……

    发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表