php smarty截取中文字符乱码问题?gb2312/utf-8


Posted in PHP onNovember 07, 2011

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

以上代码完整实现了truncate的原有功能,而且可以同时兼容GB2312和UTF-8编码,在判断字符长度的时候,一个中文字符算1.0,一个英文字符算0.5,所以在截取子字符串的时候不会出现参差不齐的情况.
插件的使用方式没有特别之处,这里简单测试一下:
{$content|smartTruncate:5:".."}($content等于"A中B华C人D民E共F和G国H")
显示:A中B华C.. (中文符号长度算1.0,英文符号长度算0.5,并且考虑省略符号的长度)
不管你是使用GB2312编码还是UTF-8编码,你会发现结果都正确,这也是为什么我在插件名字里加上smart字样的原因之一。
PHP 相关文章推荐
PHP中的正规表达式(二)
Oct 09 PHP
使用PHP批量生成随机用户名
Jul 10 PHP
php chr() ord()中文截取乱码问题解决方法
Sep 08 PHP
php的ajax框架xajax入门与试用介绍
Dec 19 PHP
PHP数组无限分级数据的层级化处理代码
Dec 29 PHP
基于HBase Thrift接口的一些使用问题及相关注意事项的详解
Jun 03 PHP
php自定义函数截取汉字长度
May 15 PHP
smarty高级特性之过滤器的使用方法
Dec 25 PHP
PHP的Yii框架中使用数据库的配置和SQL操作实例教程
Mar 17 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
Jun 09 PHP
Laravel框架使用Seeder实现自动填充数据功能
Jun 13 PHP
laravel-admin的多级联动方法
Sep 30 PHP
PHP面向对象概念
Nov 06 #PHP
php 记录进行累加并显示总时长为秒的结果
Nov 04 #PHP
php 按指定元素值去除数组元素的实现方法
Nov 04 #PHP
php数组函数序列之array_search()- 按元素值返回键名
Nov 04 #PHP
php 伪造本地文件包含漏洞的代码
Nov 03 #PHP
有关php运算符的知识大全
Nov 03 #PHP
PHP读取txt文件的内容并赋值给数组的代码
Nov 03 #PHP
You might like
php fckeditor 调用的函数
2009/06/21 PHP
PHP数组循环操作详细介绍 附实例代码
2013/02/03 PHP
php利用cookie实现自动登录的方法
2014/12/10 PHP
smarty模板引擎基础知识入门
2015/03/30 PHP
PHP 芝麻信用接入的注意事项
2016/12/01 PHP
用javascript将数据库中的TEXT类型数据动态赋值到TEXTAREA中
2007/04/20 Javascript
javascript 建设银行登陆键盘
2008/06/10 Javascript
JavaScript 关键字屏蔽实现函数
2009/08/02 Javascript
js获取TreeView控件选中节点的Text和Value值的方法
2012/11/24 Javascript
js展开闭合效果演示代码
2013/07/24 Javascript
javascript禁制后退键(Backspace)实例代码
2013/11/15 Javascript
javascript 数字格式化输出的实现代码
2013/12/10 Javascript
jQuery的选择器中的通配符使用介绍
2014/03/20 Javascript
JavaScript中的console.log()函数详细介绍
2014/12/29 Javascript
javascript删除元素节点removeChild()用法实例
2015/05/26 Javascript
jquery不常用方法汇总
2015/07/26 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
2017/02/24 Javascript
基于vue循环列表时点击跳转页面的方法
2018/08/31 Javascript
微信小程序当前时间时段选择器插件使用方法详解
2018/12/28 Javascript
vue-cli3+ts+webpack实现多入口多出口功能
2019/05/30 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
2019/08/07 Javascript
vue登录注册实例详解
2019/09/14 Javascript
Vue中keep-alive组件作用详解
2020/02/04 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
Python3 入门教程 简单但比较不错
2009/11/29 Python
python中子类调用父类函数的方法示例
2017/08/18 Python
python实现装饰器、描述符
2018/02/28 Python
基于python 二维数组及画图的实例详解
2018/04/03 Python
解决pycharm无法识别本地site-packages的问题
2018/10/13 Python
对python创建及引用动态变量名的示例讲解
2018/11/10 Python
Python实现代码统计工具
2019/09/19 Python
Python getsizeof()和getsize()区分详解
2020/11/20 Python
使用HTML和CSS3绘制基本卡通图案的示例分享
2015/11/06 HTML / CSS
银行职员思想汇报
2013/12/31 职场文书
计算机毕业生求职信
2014/06/10 职场文书