PHP自帶的函數如strlen()、mb_strlen()都是通過計算字符串所占字節數來統計字符串長度的,一個英文字符占1字節。例:
$enStr = 'Hello,China!';
echo strlen($enStr); // 輸出:12
而中文則不然,做中文網站一般會選擇兩種編碼:gbk/gb2312或是utf-8。utf-8能兼容更多的字符,所以受到很多站長的喜愛。gbk與utf-8對中文的編碼不同,導致中文在gbk與utf-8編碼下所占字節也有差異。
gbk編碼下每個中文字符所占字節為2,例:
$zhStr = '您好,中國!';
echo strlen($zhStr); // 輸出:12
utf-8編碼下每個中文字符所占字節為3,例:
$zhStr = '您好,中國!';
echo strlen($zhStr); // 輸出:18
/**
*
* 中英混合字符串長度判斷
* @param unknown_type $str
* @param unknown_type $charset
*/
function strLength($str, $charset = 'utf-8') {
if ($charset == 'utf-8')
$str = iconv ( 'utf-8', 'gb2312', $str );
$num = strlen ( $str );
$cnNum = 0;
for($i = 0; $i < $num; $i ++) {
if (ord ( substr ( $str, $i + 1, 1 ) ) > 127) {
$cnNum ++;
$i ++;
}
}
$enNum = $num - ($cnNum * 2);
$number = ($enNum / 2) + $cnNum;
return ceil ( $number );
}
/**
*
* 中英混合的字符串截取
* @param unknown_type $sourcestr
* @param unknown_type $cutlength
*/
function cut_str($sourcestr, $cutlength) {
$returnstr = '';
$i = 0;
$n = 0;
$str_length = strlen ( $sourcestr ); //字符串的字節數
while ( ($n < $cutlength) and ($i <= $str_length) ) {
$temp_str = substr ( $sourcestr, $i, 1 );
$ascnum = Ord ( $temp_str ); //得到字符串中第$i位字符的ascii碼
if ($ascnum >= 224) //如果ASCII位高與224,
{
$returnstr = $returnstr . substr ( $sourcestr, $i, 3 ); //根據UTF-8編碼規范,將3個連續的字符計為單個字符
$i = $i + 3; //實際Byte計為3
$n ++; //字串長度計1
} elseif ($ascnum >= 192) //如果ASCII位高與192,
{
$returnstr = $returnstr . substr ( $sourcestr, $i, 2 ); //根據UTF-8編碼規范,將2個連續的字符計為單個字符
$i = $i + 2; //實際Byte計為2
$n ++; //字串長度計1
} elseif ($ascnum >= 65 && $ascnum <= 90) //如果是大寫字母,
{
$returnstr = $returnstr . substr ( $sourcestr, $i, 1 );
$i = $i + 1; //實際的Byte數仍計1個
$n ++; //但考慮整體美觀,大寫字母計成一個高位字符
} else //其他情況下,包括小寫字母和半角標點符號,
{
$returnstr = $returnstr . substr ( $sourcestr, $i, 1 );
$i = $i + 1; //實際的Byte數計1個
$n = $n + 0.5; //小寫字母和半角標點等與半個高位字符寬...
}
}
if ($str_length > $cutlength) {
$returnstr = $returnstr . "..."; //超過長度時在尾處加上省略號
}
return $returnstr;
}
附加:
// 中文字符串截取
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
{
switch ($charset)
{
case 'utf-8':
$char_len = 3;
break;
case 'UTF8':
$char_len = 3;
break;
default:
$char_len = 2;
}
// 小於指定長度,直接返回
if ( strlen($str) <= ($length * $char_len) )
{
return $str;
}
if ( function_exists("mb_substr") )
{
$slice = mb_substr($str, $start, $length, $charset);
}
else if ( function_exists('iconv_substr') )
{
$slice = iconv_substr($str, $start, $length, $charset);
}
else
{
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = join("", array_slice($match[0], $start, $length));
}
if ( $suffix )
{
return $slice . "…";
}
return $slice;
}
