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 相关文章推荐
IIS6+PHP5+MySQL5+Zend Optimizer+phpMyAdmin安装配置图文教程 2009年
Jun 08 PHP
ezSQL PHP数据库操作类库
May 16 PHP
JpGraph php柱状图使用介绍
Aug 23 PHP
解析php中获取url与物理路径的总结
Jun 21 PHP
getimagesize获取图片尺寸实例
Nov 15 PHP
php生成html文件方法总结
Dec 01 PHP
php图像处理类实例
Jul 28 PHP
CI框架出现mysql数据库连接资源无法释放的解决方法
May 17 PHP
ThinkPHP3.2.3实现分页的方法详解
Jun 03 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
Dec 21 PHP
PHP给源代码加密的几种方法汇总(推荐)
Feb 06 PHP
Laravel框架实现抢红包功能示例
Oct 31 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项目的方法
2006/10/09 PHP
isset和empty的区别
2007/01/15 PHP
使用XDebug调试及单元测试覆盖率分析
2011/01/27 PHP
解析PHP SPL标准库的用法(遍历目录,查找固定条件的文件)
2013/06/18 PHP
YII框架行为behaviors用法示例
2019/04/26 PHP
PHP dirname功能及原理实例解析
2020/10/28 PHP
PHP+Mysql分布式事务与解决方案深入理解
2021/02/27 PHP
JQuery UI皮肤定制
2009/07/27 Javascript
合并table相同单元格的jquery插件分享(很精简)
2011/06/20 Javascript
jQuery实现选中弹出窗口选择框内容后赋值给文本框的方法
2015/11/23 Javascript
全面解析JavaScript里的循环方法之forEach,for-in,for-of
2020/04/20 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
JavaScript对象创建模式实例汇总
2016/10/03 Javascript
Nodejs进阶:如何将图片转成datauri嵌入到网页中去实例
2016/11/21 NodeJs
浅析JS中回调函数及用法
2018/07/25 Javascript
js实现下拉框二级联动
2018/12/04 Javascript
图解JS原型和原型链实现原理
2020/09/15 Javascript
[01:19:35]DOTA2上海特级锦标赛主赛事日 - 3 败者组第三轮#2Fnatic VS OG第二局
2016/03/05 DOTA
python缩进区别分析
2014/02/15 Python
给Python中的MySQLdb模块添加超时功能的教程
2015/05/05 Python
Python随手笔记第一篇(2)之初识列表和元组
2016/01/23 Python
通过Pandas读取大文件的实例
2018/06/07 Python
python同时遍历数组的索引和值的实例
2018/11/15 Python
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
Python3.5面向对象编程图文与实例详解
2019/04/24 Python
python交互模式下输入换行/输入多行命令的方法
2019/07/02 Python
python装饰器原理与用法深入详解
2019/12/19 Python
解决Tensorboard 不显示计算图graph的问题
2020/02/15 Python
Pycharm中使用git进行合作开发的教程详解
2020/11/17 Python
机械专业应届生求职信
2013/09/21 职场文书
师范生实习的个人自我鉴定
2013/10/20 职场文书
教师职称自我鉴定
2014/02/12 职场文书
党的群众路线教育实践活动总结大会主持词
2014/10/30 职场文书
2014年学校工会工作总结
2014/12/06 职场文书
李强为自己工作观后感
2015/06/11 职场文书
Python一些基本的图像操作和处理总结
2021/06/23 Python