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高手?学会“懒惰”的编程
Dec 05 PHP
使用PHP的日期与时间函数技巧
Apr 24 PHP
php输出xml格式字符串(用的这个)
Jul 12 PHP
简单实现限定phpmyadmin访问ip的方法
Mar 05 PHP
浅析PHP中的字符串编码转换(自动识别原编码)
Jul 02 PHP
php判断数组元素中是否存在某个字符串的方法
Jun 14 PHP
ThinkPHP 404页面的设置方法
Jan 14 PHP
PHP中使用Imagick读取pdf并生成png缩略图实例
Jan 21 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
Dec 18 PHP
在openSUSE42.1下编译安装PHP7 的方法
Dec 24 PHP
基于laravel制作APP接口(API)
Mar 15 PHP
php字符串操作常见问题小结
Oct 11 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自定义函数实现JS的escape的方法示例
2016/07/07 PHP
PHP addslashes()函数讲解
2019/02/03 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
Laravel 简单实现Ajax滚动加载示例
2019/10/22 PHP
多选列表框动态添加,移动,删除,全选等操作的简单实例
2014/01/13 Javascript
jquery制作弹窗提示窗口代码分享
2014/03/02 Javascript
JQUERY实现网页右下角固定位置展开关闭特效的方法
2015/07/27 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
jQuery幻灯片带缩略图轮播效果代码分享
2015/08/17 Javascript
js实现对ajax请求面向对象的封装
2016/01/08 Javascript
多功能jQuery树插件zTree实现权限列表简单实例
2016/07/12 Javascript
原生JS实现导航下拉菜单效果
2020/11/25 Javascript
vue-router实现组件间的跳转(参数传递)
2017/11/07 Javascript
Angular使用cli生成自定义文件、组件的方法
2018/09/04 Javascript
微信小程序非跳转式组件授权登录的方法示例
2019/05/22 Javascript
JavaScript实现PC端四格密码输入框功能
2020/02/19 Javascript
解决vue一个页面中复用同一个echarts组件的问题
2020/07/19 Javascript
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
[08:56]DOTA2-DPC中国联赛2月23日Recap集锦
2021/03/11 DOTA
Python中的下划线详解
2015/06/24 Python
在Python的Django框架中包装视图函数
2015/07/20 Python
Python中list列表的一些进阶使用方法介绍
2015/08/15 Python
Python基于time模块求程序运行时间的方法
2017/09/18 Python
Linux 修改Python命令的方法示例
2018/12/03 Python
在python下实现word2vec词向量训练与加载实例
2020/06/09 Python
新手学python应该下哪个版本
2020/06/11 Python
利用python绘制正态分布曲线
2021/01/04 Python
python 装饰器的基本使用
2021/01/13 Python
详解Css3新特性应用之过渡与动画
2017/01/10 HTML / CSS
css3实现背景图片拉伸效果像桌面壁纸一样
2013/08/19 HTML / CSS
达拉斯牛仔官方商店:Dallas Cowboys Pro Shop
2018/02/10 全球购物
Nginx Rewrite使用场景及配置方法解析
2021/04/01 Servers
教你怎么用python selenium实现自动化测试
2021/05/27 Python
Python中OpenCV实现查找轮廓的实例
2021/06/08 Python
python turtle绘制多边形和跳跃和改变速度特效
2022/03/16 Python
vue实现省市区联动 element-china-area-data插件
2022/04/22 Vue.js