background image

PHP 下比较 discuz 和 ecshop 的截取字符串函数

网上看到一篇文章

 discuz 和 ecshop 截取字符串的两个函数,比较了一下两个版本的函数,

都各有局限,只能在特定的前提下使用,但是学习一下有利于拓宽思路,了解

PHP 的扩展

功能
下面一览

PHP 工程师先给出两个版本函数的源代码以及简单测试,最后我会给出一个实用

性更强的字符串截取函数。需要注意的是:这里讨论的字符串截取问题都是针对

UTF-8 编

码的中文字符串。

 

discuz 版本 
代码如下

:

 

/** 
* [discuz] 基于 PHP 没有安装 mb_substr 等扩展截取字符串,如果截取中文字则按 2 个字符
计算

 

* @param $string 要截取的字符串 
* @param $length 要截取的字符数 
* @param $dot 替换截掉部分的结尾字符串 
* @return 返回截取后的字符串 
*/

 

function

 cutstr(

$string

$length

$dot

 = '...') { 

// 如果字符串小于要截取的长度则直接返回 
// 此处使用 strlen 获取字符串长度有很大的弊病,比如对字符串“新年快乐”要截取 4 个中文
字符,

 

// 那么必须知道这 4 个中文字符的字节数,否则返回的字符串可能会是“新年快乐...” 
if

 (

strlen

(

$string

) <= 

$length

) { 

return

 

$string

// 转换原字符串中 htmlspecialchars 

$pre

 = 

chr

(1); 

$end

 = 

chr

(1); 

$string

 = 

str_replace

 ( 

array

 ('&', '"', '<', '>' ), 

array

 (

$pre

 . '&' . 

$end

$pre

 . '"' . 

$end

$pre

 . '<' . 

$end

$pre

 . '>' . 

$end

 ), 

$string

 ); 

$strcut

 = ''; 

// 初始化返回值 

// 如果是 utf-8 编码(这个判断有点不全,有可能是 utf8) 
if

 (

strtolower

 ( CHARSET ) == 'utf-8') { 

// 初始连续循环指针$n,最后一个字位数$tn,截取的字符数$noc 

$n

 = 

$tn

 = 

$noc

 = 0; 

while

 ( 

$n

 < 

strlen

 ( 

$string

 ) ) { 

$t

 = ord ( 

$string

 [

$n

] ); 

if

 (

$t

 == 9 || 

$t

 == 10 || (32 <= 

$t

 && 

$t

 <= 126)) { 

// 如果是英语半角符号等,$n 指针后移 1 位,$tn 最后字是 1 位