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在线代理转向代码
May 05 PHP
php preg_replace替换实例讲解
Nov 04 PHP
php汉字转拼音的示例
Feb 27 PHP
去除php注释和去除空格函数分享
Mar 13 PHP
主流PHP框架的优缺点对比分析
Dec 25 PHP
CodeIgniter配置之routes.php用法实例分析
Jan 19 PHP
php 变量引用与变量销毁机制详细介绍
Dec 05 PHP
PHP ADODB生成下拉列表框功能示例
May 29 PHP
php实现分页功能的详细实例方法
Sep 29 PHP
laravel请求参数校验方法
Oct 10 PHP
Thinkphp 框架扩展之应用模式实现方法分析
Apr 27 PHP
php实现简易计算器
Aug 28 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
为什么夜间收到的中波电台比白天多
2021/03/01 无线电
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
基于MySQL分区性能的详细介绍
2013/05/02 PHP
WordPress中访客登陆实现邮件提醒的PHP脚本实例分享
2015/12/14 PHP
php微信开发之带参数二维码的使用
2016/08/03 PHP
redirect_uri参数错误的解决方法(必看)
2017/02/16 PHP
jQuery中:enabled选择器用法实例
2015/01/04 Javascript
简介alert()与console.log()的不同
2015/08/26 Javascript
轻松搞定jQuery.noConflict()
2016/02/15 Javascript
Javascript自执行匿名函数(function() { })()的原理浅析
2016/05/15 Javascript
JavaScript如何实现图片懒加载(lazyload) 提高用户体验(增强版)
2016/11/30 Javascript
Cookies 和 Session的详解及区别
2017/04/21 Javascript
Vue中的数据监听和数据交互案例解析
2017/07/12 Javascript
webpack配置之后端渲染详解
2017/10/26 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧滑动,右侧不动)
2019/01/23 Javascript
[39:19]完美世界DOTA2联赛PWL S2 SZ vs LBZS 第二场 11.26
2020/11/30 DOTA
Python字符串处理函数简明总结
2015/04/13 Python
python使用clear方法清除字典内全部数据实例
2015/07/11 Python
Flask框架的学习指南之开发环境搭建
2016/11/20 Python
python 类详解及简单实例
2017/03/24 Python
django多文件上传,form提交,多对多外键保存的实例
2019/08/06 Python
Python实现的微信红包提醒功能示例
2019/08/22 Python
TensorBoard 计算图的查看方式
2020/02/15 Python
英国足球店:UK Soccer Shop
2017/11/19 全球购物
Antonioli美国在线商店:时尚前卫奢华
2019/07/29 全球购物
Orlebar Brown官网:设计师泳裤和泳装
2020/12/08 全球购物
体育学院毕业生自荐信
2013/11/03 职场文书
应届毕业生求职自荐书
2014/01/03 职场文书
农村优秀教师事迹材料
2014/08/27 职场文书
2014年有孩子的离婚协议书范本
2014/10/08 职场文书
爱国主义影片观后感
2015/06/18 职场文书
感谢信的技巧及范例
2019/05/15 职场文书
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
2021/05/18 Vue.js
只需要这一行代码就能让python计算速度提高十倍
2021/05/24 Python
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL
python函数的两种嵌套方法使用
2022/04/02 Python