IT技术博客大学习 共学习 共进步

Smarty截取中文乱码的解决办法

标点符 2010-04-06 13:56:03 浏览 3,324 次

    前面一篇文章提到的是PHP截取中文时出现乱码的解决办法。这篇文章从模板引擎Smarty的角度去解决截取中文乱码的问题。

smarty的字符串截取函数是针对拉丁字符设计的,对于像汉字这样的非单字节文字在截取时就会出现乱码问题,下面是我从网上找来的一个解决方案,因为此文被转载得很多,原始出处不详。

使用方法:打开smarty/plugins/modifier.truncate.php文件,用以下内容替换该文件:

<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
 
/**
* Smarty truncate modifier plugin
*
* Type: modifier<br>
* Name: truncate<br>
* Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and
* appending the $etc string or inserting $etc into the middle.
* @link http://smarty.php.net/manual/en/language.modifier.truncate.php
* truncate (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string
* @param integer
* @param string
* @param boolean
* @param boolean
* @return string
*/
 
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_truncate($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;
}
}
 
?>

在使用时请注意,原来截取一个汉字算两个字符,现在一个汉字算一个字符,也就是说你想要截取20个汉字,原来截取的长度要设为40,即:$str|truncate:40,而现在则变成了$str|truncate:20

    

建议继续学习

  1. Vim 中截取部分内容保存到其他文件 (阅读 7,082)
  2. windows下压缩包在linux解压乱码的解决办法 (阅读 5,304)
  3. Linux screen窗口中文乱码问题 (阅读 5,286)
  4. linux下vim的编译以及终端乱码的最终解决方案 (阅读 4,742)
  5. java中文乱码解决之道(六)—–javaWeb中的编码解码 (阅读 4,142)
  6. PHP截取图片的某个区域 (阅读 3,702)
  7. Smarty之缓存操作 (阅读 3,663)
  8. java中文乱码解决之道(一)—–认识字符集 (阅读 3,643)
  9. PHP截取汉字出现乱码的解决方法 (阅读 3,623)
  10. 解决PHPMailer邮件标题中文乱码 (阅读 3,543)