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的引用原因分析
Sep 06 PHP
探讨PHP JSON中文乱码的解决方法详解
Jun 06 PHP
php文件上传的简单实例
Oct 19 PHP
PHP的error_reporting错误级别变量对照表
Jul 08 PHP
php中file_get_content 和curl以及fopen 效率分析
Sep 19 PHP
分享PHP守护进程类
Dec 30 PHP
PHP快速生成各种信息提示框的方法
Feb 03 PHP
PHP面向对象自动加载机制原理与用法分析
Oct 14 PHP
Zend Framework实现自定义过滤器的方法
Dec 09 PHP
PHP实现限制IP访问及提交次数的方法详解
Jul 17 PHP
PHP多个图片压缩成ZIP的方法
Aug 18 PHP
Laravel5框架自定义错误页面配置操作示例
Apr 17 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
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
PHP处理bmp格式图片的方法分析
2017/07/04 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
WEB页子窗口(showModalDialog和showModelessDialog)使用说明
2009/10/25 Javascript
为radio类型的INPUT添加客户端脚本(附加实现JS来禁用onClick事件思路代码)
2010/11/11 Javascript
图片img的src不变让浏览器重新加载实现方法
2013/03/29 Javascript
Javascript连接多个数组不用concat来解决
2014/03/24 Javascript
深入探秘jquery瀑布流的实现
2016/01/30 Javascript
全面解析Bootstrap表单样式的使用
2016/09/09 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
2016/10/13 Javascript
jQuery 常见小例汇总
2016/12/14 Javascript
基于vue实现分页/翻页组件paginator示例
2017/03/09 Javascript
详解nodejs微信公众号开发——4.自动回复各种消息
2017/04/11 NodeJs
详解Nodejs之npm&amp;package.json
2017/06/15 NodeJs
bootstrap paginator分页前后台用法示例
2017/06/17 Javascript
探讨Vue.js的组件和模板
2017/10/27 Javascript
详解Vue项目编译后部署在非网站根目录的解决方案
2018/04/26 Javascript
vue.js动画中的js钩子函数的实现
2018/07/06 Javascript
微信小程序显示倒计时功能示例【测试可用】
2018/12/03 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
Vue自定义多选组件使用详解
2020/09/08 Javascript
[06:43]2018DOTA2国际邀请赛寻真——VGJ.Thunder
2018/08/11 DOTA
[42:20]Winstrike vs VGJ.S 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
pandas数据预处理之dataframe的groupby操作方法
2018/04/13 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
python实现石头剪刀布程序
2021/01/20 Python
Python实现的序列化和反序列化二叉树算法示例
2019/03/02 Python
django删除表重建的实现方法
2019/08/28 Python
在 Python 中接管键盘中断信号的实现方法
2020/02/04 Python
html5的canvas方法使用指南
2014/12/15 HTML / CSS
一套SQL笔试题
2016/08/14 面试题
绘画设计学生的个人自我评价
2013/09/20 职场文书
部队反四风对照检查材料
2014/09/26 职场文书
羊脂球读书笔记
2015/06/30 职场文书
SpringBoot2 参数管理实践之入参出参与校验的方式
2021/06/16 Java/Android