PHP中无乱码截取中文字符串的函数

function substr_for_gb2312($str,$start,$len=null)
{
  $totlelength = strlen($str);


  //特例情况
  if ($len == null) $len = $totlelength;
  if ($len ==0) return “”;
  if ($len >= $totlelength && $start == 0 ) return $str;
  if ($start > $totlelength) return “”;


  //分析$start
  if ($start < 0 )  //$start<0时,转化为$start>0时的定位.
  {
      if ( abs($start) >= $totlelength ) $start = 0;
      else $start = $totlelength – abs($start);
  }
 
  //确定起始位置,当起始位拆分某汉字时,返回值包含此汉字.
  if ($start > 0)
  {
      $i = $start-1;
      $flag = -1;
      while ($i >= 0)
      {
        if ( ord(substr($str,$i,1)) > 160)
        {
            $flag = -1*$flag;
        }
        else break;
        $i–;
      }
      if($flag==1)
      {
        $start = $start – 1;
        $len++;        //保证不位移.
      }
    }
    $str = substr($str,$start);//截除字符串$str的$start位前的字符
    $totlelength = strlen($str);


    //确定结束位置,当结束位拆分某汉字时,返回值不包含此汉字.
    if ($len<0) $len = $totlelength – abs($len);
    if ($len <= 0) return “”;
    $i=min($len,$totlelength);
    $i–;
    $flag = -1;
    while ($i >= 0)
    {
      if (ord(substr($str,$i,1))>160)
      {
          $flag=-1*$flag;
      }
      else break;
      $i–;
    }
    if($flag == 1)
      $len=$len-1;
    $subit=substr($str,0,$len);
    return $subit;
}


分析:


ord()函数判断一个字节返回的ASC码,如果大于160则为中文字符的一个字节


while函数循环计算被截取的字符串中中文字节个数,若为奇数个,说明结束位拆分了某汉字