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+AJAX传送中文会导致乱码的问题的解决方法
Sep 08 PHP
一道关于php变量引用的面试题
Aug 08 PHP
php和mysql中uft-8中文编码乱码的几种解决办法
Apr 19 PHP
php生成txt文件标题及内容的方法
Jan 16 PHP
php一行代码获取文件后缀名实例分析
Nov 12 PHP
php 删除cookie方法详解
Dec 01 PHP
php实现Linux服务器木马排查及加固功能
Dec 29 PHP
php中curl使用指南
Feb 05 PHP
LINUX下PHP程序实现WORD文件转化为PDF文件的方法
May 13 PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 PHP
php mysql PDO 查询操作的实例详解
Sep 23 PHP
Laravel5.1 框架控制器基础用法实例分析
Jan 04 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 正则匹配函数体
2009/08/25 PHP
PHP读取PPT文件的方法
2015/12/10 PHP
在openSUSE42.1下编译安装PHP7 的方法
2015/12/24 PHP
利用ajax和PHP实现简单的流程管理
2017/03/23 PHP
用正则xmlHttp实现的偷(转)
2007/01/22 Javascript
javascript 控制 html元素 显示/隐藏实现代码
2009/09/01 Javascript
基于jQuery实现的Ajax 验证用户名是否存在的实现代码
2011/04/06 Javascript
Javascript中产生固定结果的函数优化技巧
2013/01/16 Javascript
javascript仿php的print_r函数输出json数据
2013/09/13 Javascript
原生JavaScript编写俄罗斯方块
2015/03/30 Javascript
jquery中ready()函数执行的时机和window的load事件比较
2015/06/22 Javascript
JS实现的竖向折叠菜单代码
2015/10/21 Javascript
js 右侧浮动层效果实现代码(跟随滚动)
2015/11/22 Javascript
Bootstrap导航栏各元素操作方法(表单、按钮、文本)
2015/12/28 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
2016/06/07 Javascript
省市二级联动小案例讲解
2016/07/24 Javascript
对比分析Django的Q查询及AngularJS的Datatables分页插件
2017/02/07 Javascript
Bootstrap3多级下拉菜单
2017/02/24 Javascript
详解webpack 多页面/入口支持&amp;公共组件单独打包
2017/06/29 Javascript
详解Angular6 热加载配置方案
2018/08/18 Javascript
JavaScript使用类似break机制中断forEach循环的方法
2018/11/13 Javascript
Python实现二分查找算法实例
2015/05/26 Python
浅谈Django自定义模板标签template_tags的用处
2017/12/20 Python
新手常见6种的python报错及解决方法
2018/03/09 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
利用css3-animation实现逐帧动画效果
2016/03/10 HTML / CSS
手工制作的音乐盒:Music Box Attic
2019/09/05 全球购物
如何打印出当前源文件的文件名以及源文件的当前行号
2015/04/05 面试题
社区矫正工作方案
2014/06/04 职场文书
2014审计局领导班子民主生活会对照检查材料思想汇报
2014/09/20 职场文书
军训心得体会范文(2016最新篇)
2016/01/11 职场文书
合作意向书范本
2019/04/17 职场文书
商业计划书如何写?关键问题有哪些?
2019/07/11 职场文书
JavaScript实现复选框全选功能
2021/04/11 Javascript
浅析JavaScript中的变量提升
2022/06/01 Javascript