2008年8月1日 星期五

Smarty truncate雙位元字元的問題

使用Smarty的truncate功能取一字串的前n字,使用英文沒問題,但中文字會被誤截,出現FF, FD等字(Firefox中), 或出現亂碼(IE中)。這是php當中multi-byte的老問題。

解決辦法:

1.對php下手:
 用mbstring,請參考「LifeType的討論串」。

2.對Smarty下手:
 改smarty目錄下plugin裡modifier.truncate.php的function

 這是引用自網上phpbulo.com 的作法。
function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false)
{
 $start=0;
 $code="UTF-8";
 if($code == 'UTF-8')
 {
  $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";
preg_match_all($pa, $string, $t_string);

  if(count($t_string[0]) - $start > $length)
   return join('', array_slice($t_string[0], $start, $length))."...";
  return join('', array_slice($t_string[0], $start, $length));
 }
 else
 {
  $start = $start*2;
  $length = $length*2;
  $strlen = strlen($string);
  $tmpstr = '';

  for($i=0; $i<$strlen; $i++)
  {
   if($i>=$start && $i<($start+$length))
   {
    if(ord(substr($string, $i, 1))>129)
     $tmpstr.= substr($string, $i, 2);
    else
     $tmpstr.= substr($string, $i, 1);
   }
   if(ord(substr($string, $i, 1))>129)
    $i++;

  }
  if(strlen($tmpstr)<$strlen )    $tmpstr.= "...";
  return $tmpstr;
 }
}




沒有留言: