欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

dedecms 默认的 cn_substr_utf8 可能有点问题 有大用

shiping1 的头像
utf-8的情况下 中文算两个字符 英文算一个字符

在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 = '';  //为了兼容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));

cn_substr_utf8 与 cn_substr_utf82 的区别 见下面标红的一行

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;
        }
        if (ord($str[$i]) > 0x80) {
            if ($str_len > $i + 1) {
                $c = $str[$i] . $str[$i + 1];
            }
            $i++;
        } else {
            $c = $str[$i];
        }
        if ($i >= $enddd) {
            if (strlen($restr) + strlen($c) > $slen) {
                break;
            } else {
                $restr .= $c;
                break;
            }
        }
    }
    return $restr;
}

function cn_substr_utf8($str, $length, $start = 0)
{
    if (strlen($str) < $start + 1) {
        return '';
    }
    preg_match_all("/./su", $str, $ar);
    $str = '';
    $tstr = ''; //为了兼容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;
}

function cn_substr_utf82($str, $length, $start = 0)
{
    if (strlen($str) < $start + 1) {
        return '';
    }
    preg_match_all("/./su", $str, $ar);
    $str = '';
    $tstr = ''; //为了兼容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]) - 1) // phpsir 加了 -1
            {
                $str .= $ar[0][$i];
            } else {
                break;
            }
        }
    }
    return $str;
}


来自 http://www.ynpxrz.com/n780684c2026.aspx

来自 http://www.jb51.net/cms/129412.html

普通分类: