PHP中文字符串截断无乱码解决方法

6年以前  |  阅读数:406 次  |  编程语言:PHP 

一个比较好用的字符串截取函数:


    function substring($str, $start, $length){ //比较好用字符串截取函数
      $len = $length;
      if($length < 0){
      $str = strrev($str);
      $len = -$length;
      }
      $len= ($len < strlen($str)) ? $len : strlen($str);
      $tmpstr = "";
      for ($i= $start; $i < $len; $i ++)
      {
          if (ord(substr($str, $i, 1)) > 0xa0)
          {
           $tmpstr .= substr($str, $i, 2);
           $i++;
          } else {
           $tmpstr .= substr($str, $i, 1);
          }
      }
      if($length < 0) $tmpstr = strrev($tmpstr);
      return $tmpstr;
    }

使用方法示例:


    $str1 = '我是一串比较长的中文不带英文';
    $str2 = '我是一串比较长的中文带yingwen';


    $len = strlen($str1);
    echo '<br />'.$len; //return 28

    $len = strlen($str2);
    echo '<br />'.$len; //return 29

    echo '<br />';  
    echo substring($str1, 0, 11);  
    echo '<br />';
    echo substring($str2, 0, 11);    
    echo '<br />';
    echo substring($str1, 16, 28);  
    echo '<br />';
    echo substring($str2, 16, 29);  

结果显示:

28
29
我是一串比较
我是一串比较
中文不带英文
中文带yingwen

这个函数十分有用,比如用来截断比较长的文件名,但是要在中间加上...,可以这样来做:


    function formatName($str, $size){
      $len = strlen($str);
      if(strlen($str) > $size) {
        $part1 = substring($str, 0, $size / 2);
        $part2 = substring($str, $len - ($size/2), $len);
        return $part1 . "..." . $part2;
      } else {
        return $str;
      }
    }

另外,网上看到一种超级简单的中文截断解决方案,试用了一下,效果也不错:

echo substr($str1,0,10).chr(0);

原理解释:

chr(0)不是null
07null是什么都没有,而chr(0)的值是0。表示成16进制是0x00,表示成二进制是00000000
08虽然chr(0)不会显示出什么,但是他是一个字符。
09当汉字被截断时,根据编码规则他总是要把后边的其他字符拉过来一起作为汉字解释,这就是出现乱码的原因。而值为0x81到0xff与0x00组合始终都显示为"空"
10根据这一特点,在substr的结果后面补上一个chr(0),就可以防止出现乱码了

----------------------------

20120705更新:

以上方法虽好,但是偶尔还是会碰到乱码,原因未深究。不过可以用以下的方法,对UTF8字符文本屡试不爽。
注意:该方法中将汉字计算为1单位长度,英文一个字母1单位长度,所以截断时需要注意长度设置。
计算长度的方法:


    function strlen_UTF8($str)
    {
      $len = strlen($str);
      $n = 0;
      for($i = 0; $i < $len; $i++) {
        $x = substr($str, $i, 1);
        $a = base_convert(ord($x), 10, 2);
        $a = substr('00000000'.$a, -8);
        if (substr($a, 0, 1) == 0) {
        }elseif (substr($a, 0, 3) == 110) {
          $i += 1;
        }elseif (substr($a, 0, 4) == 1110) {
          $i += 2;
        }
        $n++;
      }
      return $n;
    } // End strlen_UTF8;

字符串截断函数:


    function subString_UTF8($str, $start, $lenth)
      {
        $len = strlen($str);
        $r = array();
        $n = 0;
        $m = 0;
        for($i = 0; $i < $len; $i++) {
          $x = substr($str, $i, 1);
          $a = base_convert(ord($x), 10, 2);
          $a = substr('00000000'.$a, -8);
          if ($n < $start){
            if (substr($a, 0, 1) == 0) {
            }elseif (substr($a, 0, 3) == 110) {
              $i += 1;
            }elseif (substr($a, 0, 4) == 1110) {
              $i += 2;
            }
            $n++;
          }else{
            if (substr($a, 0, 1) == 0) {
              $r[ ] = substr($str, $i, 1);
            }elseif (substr($a, 0, 3) == 110) {
              $r[ ] = substr($str, $i, 2);
              $i += 1;
            }elseif (substr($a, 0, 4) == 1110) {
              $r[ ] = substr($str, $i, 3);
              $i += 2;
            }else{
              $r[ ] = '';
            }
            if (++$m >= $lenth){
              break;
            }
          }
        }
        return join($r);
      } // End subString_UTF8;

使用方法和之前介绍的一样,比如formatName可以实现如下(这对汉字长度做了小优化):


    function formatName($str, $size){
     $len = strlen_UTF8($str);
     $one_len = strlen($str);
     $size = $size * 1.5 * $len / ($one_len);
     if(strlen_UTF8($str) > $size) {
      $part1 = subString_UTF8($str, 0, $size / 2);
      $part2 = subString_UTF8($str, $len - ($size/2), $len);
      return $part1 . "..." . $part2;
     } else {
      return $str;
     }
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
获取IMSI
将二进制数据转为16进制以便显示
文件下载
获取IMEI
贪吃蛇
双位运算符
发送邮件
PHP自定义函数获取搜索引擎来源关键字的方法
Java生成UUID
提取后缀名
年的日历图
在Zeus Web Server中安装PHP语言支持
让你成为最历害的git提交人
Yii2汉字转拼音类的实例代码
再谈PHP中单双引号的区别详解
指定应用ID以获取对应的应用名称
Python 2与Python 3版本和编码的对比
php封装的page分页类完整实例