taoCMS是基于php+sqlite/mysql的国内最小(100Kb左右)的功能完善的CMS管理系统

PHP源码阅读笔记:nl2br, ltrim, rtrim, trim函数

2013-02-22

PHP源码阅读笔记:nl2br, ltrim, rtrim, trim函数

string nl2br ( string string )

Returns string with ‘
‘ inserted before all newlines.

在代码中有注释如下:

/* it is really faster to scan twice and allocate mem once insted scanning once
and constantly reallocing */

程序先计算需要替换的个数,然后一次性计算需要分配的内存大小。从而减少了每次替换都重新分配内存的开销。

由此可见PHP源码的作者的程序优化上下了不少功夫。

源码摘抄如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
 
    str = Z_STRVAL_PP(zstr);    //    字符串开始位置
    end = str + Z_STRLEN_PP(zstr);     //    字符串结束地址
 
    /* it is really faster to scan twice and allocate mem once insted scanning once
       and constantly reallocing */
    while (str < end) {       //    计算需要替换的位置个数
        if (*str == 'r') {
            if (*(str+1) == 'n') {
                str++;
            }
            repl_cnt++;
        } else if (*str == 'n') {
            if (*(str+1) == 'r') {
                str++;
            }
            repl_cnt++;
        }
 
        str++;
    }
 
    if (repl_cnt == 0) {    //    如果没有可替换的字符串,直接返回
        RETURN_STRINGL(Z_STRVAL_PP(zstr), Z_STRLEN_PP(zstr), 1);
    }
 
 
    //    给新生成的字符串分配内存
    new_length = Z_STRLEN_PP(zstr) + repl_cnt * (sizeof("<br />") - 1);
    tmp = target = emalloc(new_length + 1);
 
    str = Z_STRVAL_PP(zstr);
 
    while (str < end) {
        switch (*str) {
            case 'r':    //    没有break,直接转下个case
            case 'n':
                *target++ = '<';
                *target++ = 'b';
                *target++ = 'r';
                *target++ = ' ';
                *target++ = '/';
                *target++ = '>';
 
                if ((*str == 'r' && *(str+1) == 'n') || (*str == 'n' && *(str+1) == 'r')) {
                    *target++ = *str++;
                }
                /* lack of a break; is intentional */
            default:
                *target++ = *str;
        }
 
        str++;
    }
 
    *target = '';    //    添加最后的结束字符
 
    RETURN_STRINGL(tmp, new_length, 0);    //    返回结果

ltrim — Strip whitespace (or other characters) from the beginning of a string

rtrim — Strip whitespace (or other characters) from the end of a string

trim — Strip whitespace (or other characters) from the beginning and end of a string

这三个函数都是调用static void php_do_trim(INTERNAL_FUNCTION_PARAMETERS, int mode)

===》PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_value, int mode TSRMLS_DC)

实现,依据不同的mode(ltrim => 1, rtrim => 2, trim => 3)实现。

对于第二个参数,指过滤的字符,在默认情况下是 空格 nrtv

在程序中可以看到过滤用的字符仅有char mask[256];即ASCII 码的256个值

在使用php_charmask(unsigned char *input, int len, char *mask TSRMLS_DC)函数创建过滤用的字符HASH数组

如果是1或3(程序实现使用的是 mode & 1),则过滤源字符串前面的字符,从头开始遍历每个字符串,直接hash判断是否是需要过滤的字符,直到第一个不是过滤字符的位置结束

如果是2或 3(程序实现使用的是 mode & 2),则过滤源字符串后面的字符,过程与前面类似。

类别:技术文章 | 阅读:194699 | 评论:0 | 标签:php c nl2br ltrim rtrim trim

想收藏或者和大家分享这篇好文章→

“PHP源码阅读笔记:nl2br, ltrim, rtrim, trim函数”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

公告

taoCMS发布taoCMS 3.0.2(最后更新21年03月15日),请大家速速升级,欢迎大家试用和提出您宝贵的意见建议。

捐助与联系

☟请使用新浪微博联系我☟

☟在github上follow我☟

标签云