关于Smarty插件中truncate截取中文乱码的解决方案

本文介绍如何为Smarty模板引擎定制一个中文字符串截断函数,解决默认truncate方法无法正确处理中文字符的问题。通过创建新的变量调节器,实现中文字符串的准确截断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        当我们使用Smarty自带的truncate变量调节器来控制字符串长度的时候,由于truncate方法只能对于英文字符进行截取,当我们截取中文字符的时候就会出现我们最不想看到的乱码,这个时候,我们可以通过改写一个新的变量调节器来截取中文字符,做到一劳永逸的效果。

        首先要知道Smarty的安装目录,打开plugins文件夹,新建一个php文件,并且命名为modifier.sbtruncate.php,然后输入一下代码:

 <?php
function smarty_modifier_mbtruncate($string, $sublen = 80, $etc = '...', $break_words = false, $middle = false)
{
    $start=0;
    $code="UTF-8";
    if($code == 'UTF-8')
    {
        //如果有中文则减去中文的个数
        $cncount=cncount($string);
        if($cncount>($sublen/2))
        {
            $sublen=ceil($sublen/2);
        }
        else
        {
            $sublen=$sublen-$cncount;
        }


        $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80


-\xbf][\x80-\xbf][\x80-\xbf]/";
        preg_match_all($pa, $string, $t_string);
        if(count($t_string[0]) - $start > $sublen) return join('', array_slice($t_string[0], $start, $sublen))."...";
        return join('', array_slice($t_string[0], $start, $sublen));
    }
    else
    {
        $start = $start*2;
        $sublen = $sublen*2;
        $strlen = strlen($string);
        $tmpstr = '';


        for($i=0; $i<$strlen; $i++)
        {
            if($i>=$start && $i<($start+$sublen))
            {
                if(ord(substr($string, $i, 1))>129)
                {
                    $tmpstr.= substr($string, $i, 2);
                }
                else
                {
                    $tmpstr.= substr($string, $i, 1);
                }
            }
            if(ord(substr($string, $i, 1))>129) $i++;
        }


        if(strlen($tmpstr)<$strlen ) $tmpstr.= "...";
        return $tmpstr;
    }
}


function cncount($str)
{
    $len=strlen($str);
    $cncount=0;


    for($i = 0; $i < $len; $i++)
    {
        $temp_str=substr($str,$i,1);
        if(ord($temp_str) > 127)  
        {
            $cncount++;
        }
    }


    return ceil($cncount/3);
}


?>


最后使用方法跟Smarty的一样,使用实例:

 {$title|sbtruncate:10:"..."}


<think>好的,我现在要解决的问题是在PHP中截取变量值的前20个字符并输出。用户提到想要修改PHP代码来实现这个功能,所以需要先了解PHP中字符串截取的相关函数。 首先,我记得PHP有几个处理字符串的函数,比如substr()和mb_substr()。substr()是基本的截取函数,但可能对多字节字符(比如中文)处理不好,而mb_substr()是专门处理多字节的,更适合中文环境。用户的需求是截取前20个字符,如果变量包含中文的话,可能需要用mb_substr(),否则用substr()就可以了。 接下来,我需要确定用户是否需要考虑字符串长度不足20的情况。比如,如果字符串本身只有15个字符,直接截取的话不会有问题,但用户提到超过一定长度要加省略号,所以可能需要判断长度,超过20的部分截断并添加“...”。不过用户的问题描述里只明确说“限制显示的内容长度为前20个字符”,并没有明确是否要加省略号,但根据参考中的引用[2]和[3],用户可能希望类似的效果。 现在看用户提供的引用资料。引用[2]和[5]提到了使用substr函数进行截取,并在超过长度时加省略号。引用[3]提到在Smarty模板中使用truncate插件,但用户现在可能需要的是纯PHP代码的解决方案。 所以,解决方案应该是使用substr()函数,截取前20个字符,然后判断原字符串长度是否超过20,如果超过就加上省略号。不过用户的问题可能只需要截取并输出前20个字符,是否添加省略号可能需要进一步确认,但根据示例中的情况,引用[2]中的做法是超过长度就截取前n个字符加省略号,所以可能用户需要这个功能。 不过用户的具体问题是“修改PHP代码以限制显示的内容长度为前20个字符”,所以可能只需要截取前20个字符,无论是否添加省略号。需要明确回答两种情况:一种是直接截取,另一种是截取并添加省略号。 现在考虑代码的实现。使用substr($str, 0, 20)可以截取前20个字节,但如果字符串包含多字节字符(比如UTF-8的中文),每个汉字占3个字节,这样截取可能会导致乱码。例如,20个字节可能只能截取6个汉字(每个3字节,6*3=18字节)加上2个字节,这可能不完整。所以正确的做法是使用mb_substr(),指定正确的编码。 因此,正确的代码应该是: $trimmed = mb_substr($str, 0, 20, 'UTF-8'); 然后判断原字符串长度是否超过20个字符,如果是,加上省略号: if (mb_strlen($str, 'UTF-8') > 20) { $trimmed .= '...'; } 然后输出$trimmed。 不过用户的问题可能没有提到多字节字符,是否需要考虑?根据引用[2]和[5]中的示例,可能用户在处理的是普通字符串,但为了安全起见,应该建议使用mb_substr()来处理多字节情况,尤其是中文字符。 总结步骤: 1. 使用mb_substr()函数截取前20个字符,指定编码为UTF-8。 2. 检查原字符串长度是否超过20,超过则添加省略号。 3. 输出处理后的字符串。 现在根据用户提供的引用,引用[5]提到substr函数的用法,但可能用户需要的是mb_substr()。需要指出两者的区别,避免乱码问题。 所以最终的代码示例可能如下: $originalString = "这是一个需要截取的字符串示例,假设它很长很长..."; $maxLength = 20; if (mb_strlen($originalString, 'UTF-8') > $maxLength) { $trimmedString = mb_substr($originalString, 0, $maxLength, 'UTF-8') . '...'; } else { $trimmedString = $originalString; } echo $trimmedString; 或者更简洁的写法: $trimmedString = mb_substr($originalString, 0, $maxLength, 'UTF-8'); if (mb_strlen($originalString, 'UTF-8') > $maxLength) { $trimmedString .= '...'; } echo $trimmedString; 不过用户可能只需要截取前20个字符,而不添加省略号,所以需要确认。但根据用户引用的内容,引用[2]和[3]都提到添加省略号,所以应该包括这种情况。 因此,回答中应该给出两种情况的代码:仅截取截取后添加省略号,并说明两者的区别,以及使用mb_substr()的重要性,尤其是处理中文等多字节字符时。 另外,要确保代码语法正确,比如使用正确的函数参数顺序:mb_substr($str, $start, $length, $encoding)。 最后,需要引用用户提供的参考资料中的内容,比如引用[2]和[5]提到了使用substr函数,但需要指出在处理多字节时建议使用mb_substr(),如引用[3]提到的truncate插件可能内部处理了多字节的情况。</think>在PHP中截取变量值的前20个字符并输出,可以使用以下方法: ### 1. 基础方法:使用`substr()`函数 适用于单字节字符(如英文): ```php $originalString = "This is a sample string to be truncated."; $trimmedString = substr($originalString, 0, 20); echo $trimmedString; // 输出前20个字符 ``` ### 2. 多字节安全方法:使用`mb_substr()`函数 **推荐用于包含中文等多字节字符的场景**: ```php $originalString = "这是一个包含中文的字符串,需要截取前20个字符。"; $trimmedString = mb_substr($originalString, 0, 20, 'UTF-8'); echo $trimmedString; // 输出前20个字符(按字符计算) ``` ### 3. 添加省略号(如果超长) 若需在截断后添加省略号: ```php $maxLength = 20; if (mb_strlen($originalString, 'UTF-8') > $maxLength) { $trimmedString = mb_substr($originalString, 0, $maxLength, 'UTF-8') . '...'; } else { $trimmedString = $originalString; } echo $trimmedString; // 例如:"这是一个包含中文的字..." ``` ### 关键点说明 - **`substr()`与`mb_substr()`的区别**: - `substr()`按字节截取,可能导致中文乱码[^5]。 - `mb_substr()`按字符截取,需指定编码(如UTF-8)[^3]。 - **省略号逻辑**:通过`mb_strlen()`判断原始长度,避免错误截断。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值