在dedecms里面 cn_substr_utf8 函数是这样的
代码如下:
/**
 *  utf-8中文截取,单字节截取模式
 *
 * @access    public
 * @param     string  $str  需要截取的字符串
 * @param     int  $slen  截取的长度
 * @param     int  $startdd  开始标记处
 * @return    string
 */
if ( ! function_exists('cn_substr_utf8'))
{
    function cn_substr_utf8($str, $length, $start=0)
    {
        if(strlen($str) < $start+1)
        {
            return '';
        }
        preg_match_all("/./su", $str, $ar);
        $str = '';
        $tstr = '';</p>
<p>        //为了兼容mysql4.1以下版本,与数据库varchar一致,这里使用按字节截取
        for($i=0; isset($ar[0][$i]); $i++)
        {
            if(strlen($tstr) < $start)
            {
                $tstr .= $ar[0][$i];
            }
            else
            {
                if(strlen($str) < $length + strlen($ar[0][$i]) )
                {
                    $str .= $ar[0][$i];
                }
                else
                {
                    break;
                }
            }
        }
        return $str;
    }
}
其中
代码如下:
if(strlen($str) < $length + strlen($ar[0][$i]) )
一行可能会造成截取后多了一个字符,可以考虑改为
代码如下:
if(strlen($str) < $length + strlen($ar[0][$i]) -1 )
测试代码如下
代码如下:
$f = "你好fasdfa你fasdf#e#";
$pos = strpos($f,'#e#');
var_dump($pos);
var_dump(cn_substr_utf8($f,$pos));
var_dump(cn_substr_utf82($f,$pos));</p>
<p>function cn_substr($str, $slen, $startdd=0)
{
 global $cfg_soft_lang;
 if($cfg_soft_lang=='utf-8')
 {
  return cn_substr_utf8($str, $slen, $startdd);
 }
 $restr = '';
 $c = '';
 $str_len = strlen($str);
 if($str_len < $startdd+1)
 {
  return '';
 }
 if($str_len < $startdd + $slen || $slen==0)
 {
  $slen = $str_len - $startdd;
 }
 $enddd = $startdd + $slen - 1;
 for($i=0;$i<$str_len;$i++)  {   if($startdd==0)   {    $restr .= $c;   }   else if($i > $startdd)
  {
   $restr .= $c;
  }</p>
<p>  if(ord($str[$i])>0x80)
  {
   if($str_len>$i+1)
   {
    $c = $str[$i].$str[$i+1];
   }
   $i++;
  }
  else
  {
   $c = $str[$i];
  }</p>
<p>  if($i >= $enddd)
  {
   if(strlen($restr)+strlen($c)>$slen)
   {
    break;
   }
   else
   {
    $restr .= $c;
    break;
   }
  }
 }
 return $restr;
}</p>
<p>function cn_substr_utf8($str, $length, $start=0)
{
 if(strlen($str) < $start+1)
 {
  return '';
 }
 preg_match_all("/./su", $str, $ar);</p>
<p> $str = '';
 $tstr = '';</p>
<p> //为了兼容mysql4.1以下版本,与数据库varchar一致,这里使用按字节截取
 for($i=0; isset($ar[0][$i]); $i++)
 {
  if(strlen($tstr) < $start)
  {</p>
<p>   $tstr .= $ar[0][$i];
  }
  else
  {</p>
<p>   if(strlen($str) < $length + strlen($ar[0][$i])  )
   {</p>
<p>    $str .= $ar[0][$i];
   }
   else
   {</p>
<p>    break;
   }
  }
 }
 return $str;
}</p>
<p>function cn_substr_utf82($str, $length, $start=0)
{
 if(strlen($str) < $start+1)
 {
  return '';
 }
 preg_match_all("/./su", $str, $ar);</p>
<p> $str = '';
 $tstr = '';</p>
<p> //为了兼容mysql4.1以下版本,与数据库varchar一致,这里使用按字节截取
 for($i=0; isset($ar[0][$i]); $i++)
 {
  if(strlen($tstr) < $start)
  {</p>
<p>   $tstr .= $ar[0][$i];
  }
  else
  {</p>
<p>   if(strlen($str) < $length + strlen($ar[0][$i]) -1 ) // phpsir 加了 -1 
   {</p>
<p>    $str .= $ar[0][$i];
   }
   else
   {</p>
<p>    break;
   }
  }
 }
 return $str;
}

