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 相关文章推荐
第四节 构造函数和析构函数 [4]
Oct 09 PHP
用windows下编译过的eAccelerator for PHP 5.1.6实现php加速的使用方法
Sep 30 PHP
PHP下一个非常全面获取图象信息的函数
Nov 20 PHP
php生成xml简单实例代码
Dec 16 PHP
PHP合并两个数组的两种方式的异同
Sep 14 PHP
zend Framework中的Layout(模块化得布局)详解
Jun 28 PHP
php将服务端的文件读出来显示在web页面实例
Oct 31 PHP
Yii框架扩展CGridView增加导出CSV功能的方法
May 24 PHP
[企业公众号]升级到[企业微信]之后发送消息失败的解决方法
Jun 30 PHP
使用PHPExcel导出Excel表
Sep 08 PHP
对php 判断http还是https,以及获得当前url的方法详解
Jan 15 PHP
Yii框架常见缓存应用实例小结
Sep 09 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 list()函数的详解
2013/06/05 PHP
PHP中set_include_path()函数相关用法分析
2016/07/18 PHP
php中文乱码问题的终极解决方案汇总
2017/08/01 PHP
PHP合并两个或多个数组的方法
2019/01/20 PHP
javascript中字符串拼接需注意的问题
2010/07/13 Javascript
jQuery中position()方法用法实例
2015/01/16 Javascript
编写自己的jQuery提示框(Tip)插件
2015/02/05 Javascript
原创jQuery弹出层插件分享
2015/04/02 Javascript
JS实现留言板功能
2017/06/17 Javascript
JavaScript基本语法_动力节点Java学院整理
2017/06/26 Javascript
JS实现页面打印(整体、局部)
2017/08/18 Javascript
jQuery zTree 异步加载添加子节点重复问题
2017/11/29 jQuery
浅谈 Vue 项目优化的方法
2017/12/16 Javascript
Angular 开发学习之Angular CLI的安装使用
2017/12/31 Javascript
基于React+Redux的SSR实现方法
2018/07/03 Javascript
Bootstrap Table 双击、单击行获取该行及全表内容
2018/08/31 Javascript
详解vue中localStorage的使用方法
2018/11/22 Javascript
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
layer.js之回调销毁对话框的例子
2019/09/11 Javascript
Vue项目中如何使用Axios封装http请求详解
2019/10/23 Javascript
[03:20]2015国际邀请赛全明星表演赛
2015/08/08 DOTA
下载给定网页上图片的方法
2014/02/18 Python
Python通过matplotlib绘制动画简单实例
2017/12/13 Python
python使用mitmproxy抓取浏览器请求的方法
2019/07/02 Python
Python time库基本使用方法分析
2019/12/13 Python
python中常见错误及解决方法
2020/06/21 Python
html svg生成环形进度条的实现方法
2019/09/23 HTML / CSS
SmartBuyGlasses丹麦:网上购买名牌太阳镜、眼镜和隐形眼镜
2016/10/01 全球购物
日本最佳原创设计品牌:Felissimo(芬理希梦)
2019/03/19 全球购物
创业计划书六个要素
2013/12/26 职场文书
应届优秀本科大学毕业生自我鉴定
2014/01/21 职场文书
上下班时间调整通知
2015/04/23 职场文书
跑出一片天观后感
2015/06/08 职场文书
MySQL update set 和 and的区别
2021/05/08 MySQL
python turtle绘图命令及案例
2021/11/23 Python
javascript之Object.assign()的痛点分析
2022/03/03 Javascript