1

在php中String是常用的类型,今天就开始阅读他的函数,本人小菜,有什么错误的地方望大神指点。

首先string的函数定义在/ext/standard/string.c文件中,这里我看的php版本是php7.1.2。

首先在对于php源码中的函数,定义方法都是PHP_FUNCTION(方法名称)

  1. 源码:

    • strtolower和strtoupper

这两个函数的源码相对比较简单,但是在文件中既出现
PHPAPI char *php_strtoupper(char *s, size_t len)
又出现了
PHPAPI zend_string *php_string_toupper(zend_string *s)
他们代码的主要算法是一样的,但是在定于strtoupper方法处是这样写的
    PHP_FUNCTION(strtoupper)
    {
        zend_string *arg;
    
        ZEND_PARSE_PARAMETERS_START(1, 1)
            Z_PARAM_STR(arg)
        ZEND_PARSE_PARAMETERS_END();
    
        RETURN_STR(php_string_toupper(arg));
    }
所以函数应该是php_string_toupper,至于php_strtoupper,由检索得这个函数可能是为内部一些方法提供的接口

PHPAPI zend_string *php_string_toupper(zend_string *s)
{
    unsigned char *c, *e; //c是字符串的起始位置,e是字符串的结束位置

    c = (unsigned char *)ZSTR_VAL(s);  //返回zeng_tring类型中数据部分val的值,也就是字符串的首地址

    e = c + ZSTR_LEN(s);  //因为是e定义的是指针类型,所以e的地址就是字符串的首地址+字符串长度,也就是'\0'的地址

    //这里使用到了COW,也就是写是拷贝
    while (c < e) {
        if (islower(*c)) {
            register unsigned char *r;
            zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0); //定义res 并为res申请地址空间

            if (c != (unsigned char*)ZSTR_VAL(s)) {  //判断c是否是原始字符串的首地址
                memcpy(ZSTR_VAL(res), ZSTR_VAL(s), c - (unsigned char*)ZSTR_VAL(s));  // 如果c地址不是原始字符串首地址,
                                                                                     //则从原始字符串的首地址开始--->当前c指向的字符串地址,这部分地址数据复制给res
            r = c + (ZSTR_VAL(res) - ZSTR_VAL(s)); //定义开始字符大小转换的标记,也就是从哪个地址开始进行字符串转换
            while (c < e) { //这里就很简单了
                *r = toupper(*c);
                r++;
                c++;
            }
            *r = '\0';  //定义字符串结束符
            return res;
        }
        c++;
    }
    return zend_string_copy(s); //如果整个字符串没有需要转换的字符,则将字符串的引用计数+1
}
这里需要说明的是,ZSTR_VAL是返回zeng_string结构体类型的数据部分的val值
struct _zend_string {
    zend_refcounted_h gc;
    zend_ulong        h;                /* hash value */
    size_t            len;
    char              val[1];  就是这个值
};

同理 ZSTR_LEN是返回len值


- ###strtolower和strtoupper###  

先暂时写到这里,后续有时间继续补充。。。。。


frankie
79 声望7 粉丝