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 相关文章推荐
mysql建立外键
Nov 25 PHP
php中文本操作的类
Mar 17 PHP
PHP性能优化工具篇Benchmark类调试执行时间
Dec 06 PHP
探讨:如何使用PhpDocumentor生成文档
Jun 25 PHP
深入Nginx + PHP 缓存详解
Jul 11 PHP
PHP 实现代码复用的一个方法 traits新特性
Feb 22 PHP
PHP实现获取客户端IP并获取IP信息
Mar 17 PHP
thinkPHP下的widget扩展用法实例分析
Dec 26 PHP
PHP实现批量上传单个文件
Dec 29 PHP
PHP实现获取并生成数据库字典的方法
May 04 PHP
php 7新特性之类型申明详解
Jun 06 PHP
laravel 5.4 + vue + vux + element的环境搭配过程介绍
Apr 26 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
德劲1103二次变频版的打磨
2021/03/02 无线电
php中计算时间差的几种方法
2009/12/31 PHP
php的闭包(Closure)匿名函数详解
2015/02/22 PHP
用php定义一个数组最简单的方法
2019/10/04 PHP
JQuery 图片延迟加载并等比缩放插件
2009/11/09 Javascript
JavaScript Event学习第八章 事件的顺序
2010/02/07 Javascript
学习并汇集javascript匿名函数
2010/11/25 Javascript
深入理解JavaScript系列(15) 函数(Functions)
2012/04/12 Javascript
javascript 事件处理、鼠标拖动效果实现方法详解
2012/05/11 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
页面get请求 中文参数方法乱码问题的快速解决方法
2016/05/31 Javascript
微信小程序 vidao实现视频播放和弹幕的功能
2016/11/02 Javascript
jQuery密码强度验证控件使用详解
2017/01/05 Javascript
微信小程序 navbar实例详解
2017/05/11 Javascript
Vue2.0 vue-source jsonp 跨域请求
2017/08/04 Javascript
vue中element组件样式修改无效的解决方法
2018/02/03 Javascript
PostgreSQL Node.js实现函数计算方法示例
2019/02/12 Javascript
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
python实现无证书加密解密实例
2014/10/27 Python
Python编程实现微信企业号文本消息推送功能示例
2017/08/21 Python
Python简单获取网卡名称及其IP地址的方法【基于psutil模块】
2018/05/24 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
马来西亚排名第一的宠物用品店:Pets Wonderland
2020/04/16 全球购物
中医药大学毕业生自荐信
2013/11/08 职场文书
安全生产先进个人材料
2014/02/06 职场文书
试用期自我鉴定范文
2014/03/20 职场文书
李敖北大演讲稿
2014/05/24 职场文书
求职信结尾怎么写
2014/05/26 职场文书
小学数学教研活动总结
2014/07/01 职场文书
中国梦团日活动总结
2014/07/07 职场文书
项目投资合作意向书
2014/07/29 职场文书
教师节学生演讲稿
2014/09/03 职场文书
JavaScript实现简单拖拽效果
2021/09/15 Javascript
Python字典的基础操作
2021/11/01 Python
「天才王子的赤字国家重生术」妮妮姆·拉雷粘土人开订
2022/03/21 日漫
Nginx 502 bad gateway错误解决的九种方案及原因
2022/08/14 Servers