dedecms 的cn_substr_utf8的商榷

在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));

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;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注