php中文字符串截断且无乱码的解决方法

发布时间:2019-12-27编辑:脚本学堂
php中文字符串截断且无乱码的解决方法,有需要的朋友可以参考下。

php中文字符串截断且无乱码的解决方法,有需要的朋友可以参考下。

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

复制代码 代码如下:
<?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;
}
?>

使用方法示例:
 

复制代码 代码如下:

<?php
$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

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

复制代码 代码如下:
<?php
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;
    }
}
?>
 

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

复制代码 代码如下:
<?php
echo substr($str1,0,10).chr(0);
?>
 

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

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

复制代码 代码如下:

<?php
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函数substr截取中文字符出现乱码的解决方法
php substr截断中文半个汉字乱码问题的解决方法
php乱码问题 utf8乱码杂谈
php截取中文字符串乱码如何解决呢
php分割GBK中文乱码的解决方法
解决php截取utf-8中文字符串时乱码的问题
如何解决php中文字符乱码,中文字符入库乱码的问题
有关php中文乱码的解决方法
php utf8 一半乱码的问题