Cricket 2019-06-27
在php中String是常用的类型,今天就开始阅读他的函数,本人小菜,有什么错误的地方望大神指点。
首先string的函数定义在/ext/standard/string.c文件中,这里我看的php版本是php7.1.2。
首先在对于php源码中的函数,定义方法都是PHP_FUNCTION(方法名称)
这两个函数的源码相对比较简单,但是在文件中既出现 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###
先暂时写到这里,后续有时间继续补充。。。。。