PHP内置的substr()函数不能对中文字符进行很好的截断处理,对于一些中英文混合的字符会出现乱码的情况。下面提供两种解决函数。
1、GB2312编码方式的截断
function
msubstr(
$str
,
$start
,
$len
){
if
(
strlen
(
$str
)-
$start
<
$len
)
return
false;
$tmpstr
=""
;
$strlen
=
$start
+
$len
;
for
(
$i
=0;
$i
<
$strlen
;
$i
++){
if
(ord(
substr
(
$str
,
$i
,1))>0xa0){
//0xa0 表示中文汉字编码的第一个编码字符ASCII 码值都大于0xa0
$tmpstr
.=
substr
(
$str
,
$i
,2);
$i
++;
}
else
{
$tmpstr
.=
substr
(
$str
,
$i
, 1);
}
}
return
$tmpstr
.
"..."
;
}
2、utf8格式下的中文字符截断
UTF-8编码的字符可能由1~3个字节组成,具体数目可以由第一个字节判断出来。(理论上可能更长,但这里假设不超过3个字节)
第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符
第一个字节大于192小于224的,它与它之后的1个字节组成一个UTF-8字符
否则第一个字节本身就是一个英文字符(包括数字和一小部分标点符号)。
//$sourcestr 是要处理的字符串
//$cutlength 为截取的长度(即字数)
function
cut_str(
$sourcestr
,
$cutlength
){
$returnstr
=
""
;
$i
=0;
$n
=0;
$str_length
=
strlen
(
$sourcestr
);
//字符串的字节数
while
((
$n
<
$cutlength
) && (
$i
<=
$str_length
)){
$temp_str
=
substr
(
$sourcestr
,
$i
,1);
$ascnum
=Ord(
$temp_str
);
//得到字符串中第$i位字符的ascii码
if
(
$ascnum
>=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
;
}