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 06 PHP
解决GD中文乱码问题
Feb 14 PHP
php数据入库前清理 注意php intval与mysql的int取值范围不同
Dec 12 PHP
php 文件上传类代码
Aug 06 PHP
PHP可逆加密/解密函数分享
Sep 25 PHP
PHP程序员不应该忽略的3点
Oct 09 PHP
浅谈php7的重大新特性
Oct 23 PHP
yii2局部关闭(开启)csrf的验证的实例代码
Jul 10 PHP
php框架CodeIgniter使用redis的方法分析
Apr 13 PHP
Laravel框架Request、Response及Session操作示例
May 06 PHP
php使用fputcsv实现大数据的导出操作详解
Feb 27 PHP
yii框架结合charjs实现统计30天数据的方法
Apr 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 注释规范
2012/03/29 PHP
PHP 杂谈《重构-改善既有代码的设计》之一 重新组织你的函数
2012/04/09 PHP
php生成唯一的订单函数分享
2015/02/02 PHP
PHP实现多关键字加亮功能
2016/10/21 PHP
php获取linux命令结果的实例
2017/03/13 PHP
深入聊聊Array的sort方法的使用技巧.详细点评protype.js中的sortBy方法
2007/04/12 Javascript
firefox中用javascript实现鼠标位置的定位
2007/06/17 Javascript
基于Jquery的开发个代阴影的对话框效果代码
2011/07/28 Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
2013/03/06 Javascript
Extjs单独定义各组件的实例代码
2013/06/25 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
js获取及修改网页背景色和字体色的方法
2015/12/29 Javascript
RequireJS简易绘图程序开发
2016/10/28 Javascript
JavaScript面向对象分层思维全面解析
2016/11/22 Javascript
mui back 返回刷新页面的实例
2017/12/06 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
2018/10/29 Javascript
Vue组件教程之Toast(Vue.extend 方式)详解
2019/01/27 Javascript
Vue开发之封装分页组件与使用示例
2019/04/25 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
2020/03/17 Javascript
JavaScript实现页面高亮操作提示和蒙板
2021/01/04 Javascript
Python字符串详细介绍
2015/05/09 Python
用生成器来改写直接返回列表的函数方法
2017/05/25 Python
Python网络编程详解
2017/10/31 Python
Python利用公共键如何对字典列表进行排序详解
2018/05/19 Python
Django项目中model的数据处理以及页面交互方法
2018/05/30 Python
python networkx 包绘制复杂网络关系图的实现
2019/07/10 Python
解决python虚拟环境切换无效的问题
2020/04/30 Python
15款Python编辑器的优缺点,别再问我“选什么编辑器”啦
2020/10/19 Python
中国领先的专业演出票务网:永乐票务
2016/08/29 全球购物
房地产销售主管岗位职责
2015/02/13 职场文书
辞职信模板(中英文版)
2015/02/27 职场文书
幼儿园教师自我评价
2015/03/04 职场文书
买卖合同纠纷代理词
2015/05/25 职场文书
2019年关于小学生课外阅读情况的分析报告
2019/12/02 职场文书
WINDOWS下安装mysql 8.x 的方法图文教程
2022/04/19 MySQL
flex布局中使用flex-wrap实现换行的项目实践
2022/06/21 HTML / CSS