ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案
好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的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模板中截取包含中英文混合的字符串乱码的解决方案的更多相关文章
- 在smarty模板中截取指定长度的字符串
在smarty模板中截取指定长度的字符串,可使用truncate这个插件. 用法: {{$data.value|truncate:28:'...'}} 28个字节14个字数输出,多余部分输出...,一 ...
- SMARTY模板中如何使用get,post,request,cookies,session,server变量
{$smarty}保留变量不需要从PHP脚本中分配,是可以在模板中直接访问的数组类型变量,通常被用于访问一些特殊的模板变量.例如,直接在模板中访问页面请求变量.获取访问模板时的时间戳.直接访问PHP中 ...
- 在smarty模板中使用PHP函数的方法
在smarty模板中如果要在显示的资料使用php函数时,如果是只有一个参数的函数比如说去空白的trim会写成 sample1 代码如下: <{$colname|trim}> 那如果使用像i ...
- thinkphp在模板中使用php的函数
thinkphp在模板中使用php的函数 使用 {:函数名} 的形式 例如: // 获取 session 中存的值 {:session('admin.loginname')} // 输出当前日期 {: ...
- smarty模板中引用常量没效果
在thinkphp框架中使用Thinkph的模板引擎,css,js等都没问题,配置为smarty模板引擎后没效果,如图 代码为,$Smarty的s是大写,此时页面不能引入常量,改为小写后正常了. &l ...
- 如何在smarty模板中执行php代码
Smarty模板主要的目的是分离逻辑层和表现层,所以在模板中不应该包含逻辑部分,逻辑层也不应该含有HTML.要在模板中插入逻辑程序的这种做法"非常"不被推荐,在你的case中. 如 ...
- 在thinkphp框架模板中引用session
我已经将模板引擎配置为smarty,在模板中使用常量是写为 {$smarty.const.ADMIN_IMG} 到使用到session的值时这样写 {$smarty.session.mg_name}
- 判断字符串中是否包含指定的内容&&字符串截取方法比较说明
1.使用indexOf()方法 方法说明: 作用:indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置(从前向后查找). 语法:stringObject.indexOf(searc ...
- [smarty] 在smarty模板中使用smarty变量初始化 javascript 变量的问题
// 总结:// 1/ 在smarty 模板文件中,使用从php中assign过来的smarty变量,一定需要使用双引号或单引号来括住smarty变量,如:var title="<!- ...
随机推荐
- Java多线程基础——对象及变量并发访问
在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...
- System.Guid ToString五中格式
参考:https://msdn.microsoft.com/en-us/library/97af8hh4.aspx 测试代码: using System; using System.Collectio ...
- 微软发布VSBT,无需安装Visual Studio即可实现项目编译
安装了Visual Studio的那些使用微软平台的开发者通常能够非常容易地操作自己的项目:打开解决方案,修改内容,设置好所有必须的文件以及配置后编译项目.但是在构建服务器或者持续交付系统等没有安装V ...
- eclipse如何添加Memory Analyzer
①启动Eclipse,并打开"Install New software..."对话框: ②点击Add,如图: ③点击OK,最后一直点next,完成
- Android 微信第三方登录(个人笔记)
今天在写微信登录,花了半天时间搞定.然后写下自己的笔记,希望帮助更多的人...欢迎各位指教. 微信授权登录,官方说的不是很清楚.所以导致有一部分的坑. 微信注册应用平台的应用签名,下载 微信签名生成工 ...
- SqlServer简单数据分页
手边开发的后端项目一直以来都用的.NET MVC框架,访问数据库使用其自带的EF CodeFirst模式,写存储过程的能力都快退化了 闲来无事,自己写了条分页存储过程,网上类似的文章多的是,这里只列了 ...
- System进程(pid=4)占用80端口的解决方案
问题 Mail服务器在安装TFS服务(含SQLServer2016)后启动不了网页服务. 排查问题 使用命令查看端口占用情况 netstat -nao | find ":80" n ...
- 使用PushSharp给iOS应用推送消息
PushSharp是一个C#编写的服务端类库,用于推送消息到各种客户端,支持iOS(iPhone/iPad).Android.Windows Phone.Windows 8.Amazo.Blackbe ...
- ABP理论之时间
返回总目录 本篇目录 介绍 Clock 时区 绑定器和转换器 介绍 虽然有些应用针对的是一个特定的时区,但是也有一些应用针对多个不同的时区.为了满足这些需求,ABP为datetime操作提供了通用的基 ...
- 《高性能javascript》一书要点和延伸(上)
前些天收到了HTML5中国送来的<高性能javascript>一书,便打算将其做为假期消遣,顺便也写篇文章记录下书中一些要点. 个人觉得本书很值得中低级别的前端朋友阅读,会有很多意想不到的 ...