Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2141439
  • 博文数量: 82
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 880
  • 用 户 组: 普通用户
  • 注册时间: 2005-03-14 00:01
文章分类

全部博文(82)

文章存档

2014年(1)

2011年(1)

2009年(8)

2008年(11)

2007年(13)

2006年(26)

2005年(22)

我的朋友

分类:

2007-04-13 10:59:53

改编的dedecms 4.0 的utf-8版本,在后台发表文章时常出错,提示archives表写出错,改写了相应的php,看到提示,原来是中文截取出错,导致没有引号闭合,所以字段提示tool long.觉得数据库操作的setquery函数的加引号有问题,不过发觉在之前已经变了.在include/inc_functions.php中,有cn_substr函数,这是针对gbk的双字节编码的.所以utf8时出错.于是用下面的函数代替
 
 

/**
    UTF-8编码的字符可能由1~3个字节组成, 具体数目可以由第一个字节判断出来。(理论上可能更长,但这里假设不超过3个字节)
    第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符
    第一个字节大于192小于224的,它与它之后的1个字节组成一个UTF-8字符
    否则第一个字节本身就是一个英文字符(包括数字和一小部分标点符号)。
    参数:str原始字符串,len截取长度,start起始字符位置
*/
function cn_substr($str, $len, $start = 0) {     
    $restr = '';
    $length = strlen($str); //原字节数
    if ($len >= $length && $start = 0) {
        //本来就不够长,直接返回
        return $str;
    }
    if ($length < ($start + 1)) {
        //起点已经到尾了,返回空
        return '';
    }
    if ($length < $start + $len) {
        //起点+截取,超过总长就只到总长
        $len = $length - $start;
    }
    $end = $start + $len; //结束处
    $i = 0;
    while ($i < $end) {
     $temp = substr($str, $i, 1);
     $asc = ord($temp); //得到$i字节的ascii码
     if ($asc >= 224) {
         //如ASCII位高于224,3个连续字符为一个宽字符
         if ($i >= $start && $i <= ($end - 3)) {
             $restr .= substr($str, $i, 3);
         }
         $i += 3;
     }elseif ($asc >= 192) {
         //如ASCII位高于192,2个连续字符为一个宽字符
         if ($i >= $start && $i <= ($end - 2)) {
             $restr .= substr($str, $i, 2);
         }
         $i += 2;
     }else {
         //ASCII为192下的只有一个字节
         if ($i >= $start && $i <= ($end - 1)) {
             $restr .= $temp;
         }
         $i++;
     }    
    }
    return $restr;
}

阅读(748) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~