PHP截取UTF8字符串

from: http://mengqing.org/archives/php-cut-utf8-string.html

想必很多人从一开始接触编程到现在,都有一个惯性思维:英文字符占用一个字节,中文字符占用两个字节。不错,英文字符是占用一个字节,但中文字符占用两个字节是相对于GBK编码而言(当然,其他一些编码如GB2312也是),但是在时下国际流行的UTF8编码中,一个中文字符占用3个字节。不要惊讶,这是一个事实,而且应该成为一个常识。
UTF8编码可能出现一个字符占用1个、2个、3个甚至更多字节的情况,如英文字符abc占用一个字节,中文字符占用三个字节,那么什么字符占用两个字节呢?这个问题我一开始并没有发现,只是前几天有人留言,首页的评论截取竟然出现了乱码的情况:


最开始并没有发现这两个乱码出现的问题在哪里,后来仔细验证了下,发现是处在·这个字符上(键盘左上角,中文输入法下),它占用两个字节。而emlog的截取字符串函数,除了英文字符外,默认其他的都占三个字节了,因此导致乱码出现。
查阅了相关资料,得出了一个结论:UTF8编码的字符中,第一个字节ASCII值大于等于224的,其与之后的2个字节一起组成一个UTF8字符,第一个字节ASCII值大于192等于小于224的,其与之后的1个字节组成一个UTF-8字符,第一个字节ASCII值小于192的,其本身成为一个UTF8字符。于是在PHP中将·字符的ASCII打印出来,第一个字节是194,第二个字节是183,木有第三个字节了,于是截取的字符中,若包含·字符,就会出现乱码了。
问题找到,解决方案也就很简单了,分别判断处理下就OK。写了如下函数用于截取:

<?php

function truncate($input, $length, $suffix = '...')
{
    if(strlen($input) <= $length){
        return $input;
    }
    $i = 0;
    $sb = array();
    while($i < $length - strlen($suffix)){
        $ord = ord(substr($input, $i, 1));
        $real_char_length = 1;
        if($ord >= 224){
            $real_char_length = 3;
        }elseif($ord >= 192){
            $real_char_length = 2;
        }else{
            $real_char_length = 1;
        }
        $sb[] = substr($input, $i, $real_char_length);
        $i += $real_char_length;
    }
    return implode('', $sb) . $suffix;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值