好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下:

出现乱码的原因:

对于字符串的截取,truncate函数只适合英文用户,对与中文用户来说,使用 truncate会出现乱码,而且对于中文英文混合串来说,截取同样个数的字符串,实际显示长度上却不同,一个中文的长度大致相当于两个英文的长度。此外,truncate不能同时兼容GB2312、UTF-8等编码。

解决方法:自己写一个扩展类使用

ThinkPHP使用的smarty的truncate变量调节器所在的类文件位置:ThinkPHP\Library\Vendor\Smarty\plugins,其中有一个就是modifier.truncate.php,我们不用这个,我们自己写一个来实现

文件名:modifier.smartTruncate.php

<?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 < strlen($string); $i += $bytes)
{
$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 < 0)
{
$start = max(smartStrlen($string) + $start, 0);
}
for($i = 0; $i < strlen($string); $i += $bytes)
{
if($start <= 0)
{
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 < strlen($string); $j += $bytes)
{
if($length <= 0)
{
break;
}
if(($bytes = ord(substr($string, $j, 1)) > 127 ? $number : 1) > 1)
{
if($length < 1.0)
{
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;
}
}
?>

注意:在判断字符长度时,一个中文字符算1.0,一个英文字符算0.5,截取子字符串时不会出现参差不齐的情况.

使用方法:

{$content|smartTruncate:5:"..."}

ok,测试没有问题有问欢迎指出

ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案的更多相关文章

  1. 在smarty模板中截取指定长度的字符串

    在smarty模板中截取指定长度的字符串,可使用truncate这个插件. 用法: {{$data.value|truncate:28:'...'}} 28个字节14个字数输出,多余部分输出...,一 ...

  2. SMARTY模板中如何使用get,post,request,cookies,session,server变量

    {$smarty}保留变量不需要从PHP脚本中分配,是可以在模板中直接访问的数组类型变量,通常被用于访问一些特殊的模板变量.例如,直接在模板中访问页面请求变量.获取访问模板时的时间戳.直接访问PHP中 ...

  3. 在smarty模板中使用PHP函数的方法

    在smarty模板中如果要在显示的资料使用php函数时,如果是只有一个参数的函数比如说去空白的trim会写成 sample1 代码如下: <{$colname|trim}> 那如果使用像i ...

  4. thinkphp在模板中使用php的函数

    thinkphp在模板中使用php的函数 使用 {:函数名} 的形式 例如: // 获取 session 中存的值 {:session('admin.loginname')} // 输出当前日期 {: ...

  5. smarty模板中引用常量没效果

    在thinkphp框架中使用Thinkph的模板引擎,css,js等都没问题,配置为smarty模板引擎后没效果,如图 代码为,$Smarty的s是大写,此时页面不能引入常量,改为小写后正常了. &l ...

  6. 如何在smarty模板中执行php代码

    Smarty模板主要的目的是分离逻辑层和表现层,所以在模板中不应该包含逻辑部分,逻辑层也不应该含有HTML.要在模板中插入逻辑程序的这种做法"非常"不被推荐,在你的case中. 如 ...

  7. 在thinkphp框架模板中引用session

    我已经将模板引擎配置为smarty,在模板中使用常量是写为 {$smarty.const.ADMIN_IMG} 到使用到session的值时这样写 {$smarty.session.mg_name}

  8. 判断字符串中是否包含指定的内容&&字符串截取方法比较说明

    1.使用indexOf()方法 方法说明: 作用:indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置(从前向后查找). 语法:stringObject.indexOf(searc ...

  9. [smarty] 在smarty模板中使用smarty变量初始化 javascript 变量的问题

    // 总结:// 1/ 在smarty 模板文件中,使用从php中assign过来的smarty变量,一定需要使用双引号或单引号来括住smarty变量,如:var title="<!- ...

随机推荐

  1. In-Memory:在内存中创建临时表和表变量

    在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...

  2. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  3. jQuery之ajax实现篇

    jQuery的ajax方法非常好用,这么好的东西,你想拥有一个属于自己的ajax么?接下来,我们来自己做一个简单的ajax吧. 实现功能 由于jq中的ajax方法是用了内置的deferred模块,是P ...

  4. SQLSERVER走起微信公众帐号全新改版 全新首页

    SQLSERVER走起微信公众帐号全新改版 全新首页 今天,SQLSERVER走起微信公众帐号增加了首页功能 虽然还是订阅号,不过已经对版面做了比较大的修改,希望各位亲用得放心.用得安心O(∩_∩)O ...

  5. CRL快速开发框架系列教程三(更新数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  6. 张高兴的 UWP 开发笔记:横向 ListView

    ListView 默认的排列方向是纵向 ( Orientation="Vertical" ) ,但如果我们需要横向显示的 ListView 怎么办? Blend for Visua ...

  7. BlockingCollection使用

    BlockingCollection是一个线程安全的生产者-消费者集合. 代码 public class BlockingTest { BlockingCollection<int> bc ...

  8. jquery中的$(document).ready(function() {});

    当文档载入时执行function函数里的代码, 这部分代码主要声明,页面加载后 "监听事件" 的方法.例如: $(document).ready( $("a") ...

  9. BPM与 SAP & Oracle EBS集成解决方案分享

    一.需求分析 SAP和Oracle EBS都是作为全球顶级的的ERP产 品,得到了众多客户的青睐.然而由于系统庞大.价格昂贵以及定位不同,客户在实施过程中经常会面临以下困惑: 1.SAP如何实现&qu ...

  10. 怎样两个月完成Udacity Data Analyst Nanodegree

    在迷恋数据科学很久后,我决定要在MOOC网站上拿到一份Data Science的证书.美国三个MOOC网站,Udacity上的课程已经被分成了数个nanodegree,每个nanodegree都是目前 ...