Home  >  Article  >  php教程  >  smarty中英文多编码字符截取乱码问题解决方法

smarty中英文多编码字符截取乱码问题解决方法

WBOY
WBOYOriginal
2016-06-06 20:18:491083browse

这篇文章主要介绍了smarty中英文多编码字符截取乱码问题解决方法,涉及到对原有smartTruncate的修改,非常具有实用价值,需要的朋友可以参考下

本文实例讲述了smarty中英文多编码字符截取乱码问题解决方法,分享给大家供大家参考。具体方法如下:

一般网站页面的显示都不可避免的会涉及子字符串的截取,这个时候truncate就派上用场了,但是它只适合英文用户,对与中文用户来说,使用 truncate会出现乱码,而且对于中文英文混合串来说,截取同样个数的字符串,实际显示长度上却不同,视觉上会显得参差不齐,影响美观。这是因为一个中文的长度大致相当于两个英文的长度。此外,truncate也不能同时兼容GB2312, UTF-8等编码。
改良的smartTruncate: 文件名:modifier.smartTruncate.php
具体代码如下:

复制代码 代码如下:

function smartDetectUTF8($string)
{
    static $result = array();
    if(! array_key_exists($key = md5($string), $result))
    {
        $utf8 = "
            /^(?:
                [\x09\x0A\x0D\x20-\x7E]                            # ASCII
                | [\xC2-\xDF][\x80-\xBF]                             # non-overlong 2-byte
                | \xE0[\xA0-\xBF][\x80-\xBF]                       # excluding overlongs
                | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}           # straight 3-byte
                | \xED[\x80-\x9F][\x80-\xBF]                      # excluding surrogates
                | \xF0[\x90-\xBF][\x80-\xBF]{2}                 # planes 1-3
                | [\xF1-\xF3][\x80-\xBF]{3}                          # planes 4-15
                | \xF4[\x80-\x8F][\x80-\xBF]{2}                  # plane 16
            )+$/xs
        ";
        $result[$key] = preg_match(trim($utf8), $string);
    }
    return $result[$key];
}
function smartStrlen($string)
{
    $result = 0;
    $number = smartDetectUTF8($string) ? 3 : 2;
    for($i = 0; $i     {
        $bytes = ord(substr($string, $i, 1)) > 127 ? $number : 1;
        $result += $bytes > 1 ? 1.0 : 0.5;
    }
    return $result;
}
function smartSubstr($string, $start, $length = null)
{
    $result = '''';
    $number = smartDetectUTF8($string) ? 3 : 2;
    if($start     {
        $start = max(smartStrlen($string) + $start, 0);
    }
    for($i = 0; $i     {
        if($start         {
            break;
        }
        $bytes = ord(substr($string, $i, 1)) > 127 ? $number : 1;
        $start -= $bytes > 1 ? 1.0 : 0.5;
    }
    if(is_null($length))
    {
        $result = substr($string, $i);
    }
    else
    {
        for($j = $i; $j         {
            if($length             {
                break;
            }
            if(($bytes = ord(substr($string, $j, 1)) > 127 ? $number : 1) > 1)
            {
                if($length                 {
                    break;
                }
                $result .= substr($string, $j, $bytes);
                $length -= 1.0;
            }
            else
            {
                $result .= substr($string, $j, 1);
                $length -= 0.5;
            }
        }
    }
    return $result;
}
function smarty_modifier_smartTruncate($string, $length = 80, $etc = ''...'',
                                       $break_words = false, $middle = false)
{
    if ($length == 0)
        return '''';
    if (smartStrlen($string) > $length) {
        $length -= smartStrlen($etc);
        if (!$break_words && !$middle) {
            $string = preg_replace(''/\s+?(\S+)?$/'', '''', smartSubstr($string, 0, $length+1));
        }
        if(!$middle) {
            return smartSubstr($string, 0, $length).$etc;
        } else {
            return smartSubstr($string, 0, $length/2) . $etc . smartSubstr($string, -$length/2);
        }
    } else {
        return $string;
    }
}
?>


以上代码完整实现了truncate的原有功能,而且可以同时兼容GB2312和UTF-8编码,在判断字符长度的时候,一个中文字符算1.0,一个英文字符算0.5,所以在截取子字符串的时候不会出现参差不齐的情况.
插件的使用方式没有特别之处,这里简单测试一下:

复制代码 代码如下:

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn