Smarty内置的truncate 截取中文出现乱码

为了前端的美观,我用Smarty内置的truncate函数进行字符长度控制,比如有些文章的标题太长了,并且实际上它没有必要完全显示出来。用truncate是可以截取,比如说是这样:

 代码如下 复制代码
{$articleTitle|truncate:11:"...":true}

但是如果标题为中文,那么就很容易出现乱码!这是因为Smarty的truncate截取的是字符(占一个字节),但是如果是中文,例如UTF-8(占3个字节),那么在截取的时候这里的参数11是字节数,如果是中文,则它实际上是截取3个汉字(9个字节),剩下的2字节不能表示一个汉字,那么它就会以乱码的形式显示出来!

从网上找了一个解决办法,还是不错的:

 代码如下 复制代码

<?php
function smarty_modifier_truncate_utf($string, $length = 80, $etc = '...')

{
 $result = '';
 $string = html_entity_decode(trim(strip_tags($string)), ENT_QUOTES, 'utf-8');
 for($i = 0, $j = 0; $i < strlen($string); $i++)
 {
  if($j >= $length)
  {
   for($x = 0, $y = 0; $x < strlen($etc); $x++)
   {
    if($number = strpos(str_pad(decbin(ord(substr($string, $i, 1))), 8, '0', STR_PAD_LEFT), '0'))
    {
     $x += $number - 1;
     $y++;
    }
    else
    {
     $y += 0.5;
    }
   }
   $length -= $y;
   break;
  }
  if($number = strpos(str_pad(decbin(ord(substr($string, $i, 1))), 8, '0', STR_PAD_LEFT), '0'))
  {
   $i += $number - 1;
   $j++;
  }
  else
  {
   $j += 0.5;
  }
 }
 for($i = 0; (($i < strlen($string)) && ($length > 0)); $i++)
 {
  if($number = strpos(str_pad(decbin(ord(substr($string, $i, 1))), 8, '0', STR_PAD_LEFT), '0'))
  {
   if($length < 1.0)
   {
    break;
   }
   $result .= substr($string, $i, $number);
   $length -= 1.0;
   $i += $number - 1;
  }
  else
  {
   $result .= substr($string, $i, 1);
   $length -= 0.5;
  }
 }
 $result = htmlentities($result, ENT_QUOTES, 'utf-8');
 if($i < strlen($string))
 {
  $result .= $etc;
 }
 return $result;
}
?>

其实原理很简单,就是每次从字符串中取出一个字符(这个包括英文字母、符号、汉字等等),然后将其转为ASCII码,至于为什么要转为ASCII码,因为每个字符对应于唯一的一个ASCII码,而且其分布还是有规律的,比如说任意的一个汉字的ASCII码都大于255。这样我们就可以对字符进行处理了,如果当前字符为英文字母或者是可打印的符号(ASCII值从0~254),那么截取长度+1,如果当前字符为汉字(ASCII值>255),那么截取长度就+3(UTF-8下)。这样循环结束后也就知道了实际需要截取的是多少个字节数了!

    忘了说了,将上面的函数写到modifier.truncate_utf.php这个文件中,然后将其放在smarty的plugins目录下,调用的时候:

 代码如下 复制代码

<{$topic|truncate_utf:11:"..."}>

时间: 2024-08-28 06:13:11

Smarty内置的truncate 截取中文出现乱码的相关文章

PHP模板引擎Smarty内置变量调解器用法详解_php实例

本文实例讲述了PHP模板引擎Smarty内置变量调解器用法.分享给大家供大家参考,具体如下: Smarty 中的变量调解器相当于函数,其调用方式为:通过 "|" 后面直接跟调解器函数名,如果有参数,得加在 ":" 后面,多个参数的话,累加即可. 下面为您介绍 Smarty 中内置的变量调解器: 1.capitalize 将变量里的所有单词首字大写.参数值 boolean 型决定带数字的单词,首字是否大写.默认不大写 index.php $tpl->assign

smarty内置函数config_load用法实例_php实例

本文实例讲述了smarty内置函数config_load用法.分享给大家供大家参考.具体如下: {config_load}用于从配置文件中,加载到配置变量.详细用法如下: 配置文件:foo.conf 说明:[Table] 和 [Customer] 表示段落名称. 复制代码 代码如下: [Table] pageTitle = "this is mine" bodyBgColor = "#eee" tableBorderSize = 3 tableBgColor = &

smarty内置函数foreach用法实例_php实例

本文实例讲述了smarty内置函数foreach用法.分享给大家供大家参考.具体如下: 输出文件:index.php 复制代码 代码如下: <?php require_once('libs/Smarty.class.php'); $smarty = new Smarty(); $smarty->setTemplateDir($_SERVER['DOCUMENT_ROOT']."/php/templates/"); $smarty->setCompileDir($_SE

smarty内置函数section的用法_php实例

本文实例讲述了smarty内置函数section的用法.分享给大家供大家参考.具体分析如下: foreach函数可以做到section能做的一切,所以一般都用foreach,这里也详细说下section的用法.section只能遍历索引数组,而不能遍历关联数组. 数组键值按倒序输出实例: 模板文件:temp.htm 复制代码 代码如下: {section name=foo loop=$name step=-1} {$name[foo]} {/section} 参数说明: name为section

smarty内置函数capture用法分析_php实例

本文实例讲述了smarty内置函数capture用法.分享给大家供大家参考.具体分析如下: {capture}可以捕获标记范围内的输出内容,并存到变量中而不显示.有三种用法, 代码如下: 复制代码 代码如下: {capture name="banner"}aaaaaa{/capture} {$smarty.capture.banner} <hr /> {capture assign="foo"}bbbbbb{/capture} {$foo} <hr

smarty内置函数{loteral}、{ldelim}和{rdelim}用法实例_php技巧

本文实例讲述了smarty内置函数{loteral}.{ldelim}和{rdelim}用法.分享给大家供大家参考.具体如下: {ldelim}和{rdelim}分别是smarty标识的左分隔符和右分隔符.如下面的javascript代码可以这么使用. 模板文件temp.htm如下: 复制代码 代码如下: <script language="javascript" type="text/javascript"> function myfunction()

php 解决substr()截取中文字符乱码问题_php技巧

在php中如果我要用substr()截取字符串全英文的没问题,如果包括有中文或英文就会悲剧了,但大家也 别切我们可以使用其它办法来解决. php截取中文字符串出现乱码,这是最近发现的事情,先前我曾经写过一篇关于自动生成meta信息的文章,那篇关于利用php截取文章前多少字作为description方法,但是出现了IE6无法加载CSS的现象,这里做一个补充. 首先要明确这么一个问题,之所以会出现IE6偶尔无法加载CSS的现象,是因为文件出现了乱码,导致后面的加载CSS的link无法被IE6正确解析

php substr()函数截取中文字符串乱码

php截取中文字符串出现乱码,这是最近发现的事情,先前我曾经写过一篇关于自动生成meta信息的文章 ,那篇关于利用php截取文章前多少字作为description方法,但是出现了IE6无法加载CSS的现象,这里 做一个补充.   首先要明确这么一个问题,之所以会出现IE6偶尔无法加载CSS的现象,是因为文件出现了乱码,导致后 面的加载CSS的link无法被IE6正确解析.因此就看到了一个纯HTML页面,没有CSS,赤裸裸! 明确了问题,剩下的问题就好解决了,就是防止乱码,既然万戈所提供的函数出现

php截取中文字符串不乱码的方法

 利用php内置方法mb_substr截取中文不乱码,使用起来非常简单,大家参考使用吧  GBK编码截取示例   代码如下: $str = '我是谁';  //gbk编码的字符串 echo mb_substr($str, 0, 1, 'gbk'); //输出 我     mb_substr方法比substr多一个参数,用来指定字符串编码.   utf-8编码截取示例   [code] $str = '我abc是谁';  //utf-8编码的字符串 echo mb_substr($str, 0,