我要把explode函数的功能分离出来 ext/string.c里有函数PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) PHPAPI是什么?这个以后找到了再说 zval是什么?在/Zend/zend.h这个文件里,定义了zval的structstruct _zval_struct {继续看explode这个函数 char *p1, *p2, *endp; endp = Z_STRVAL_P(str) + Z_STRLEN_P(str); 查找Z_STRVAL_P,在/Zend/zend_operators.h这个文件里#define Z_STRVAL(zval) (zval).value.str.val #define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)ok,找到了。 继续看explode这个函数 p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp); 查找php_memnstr,在/Zend/zend_operators.h这个文件里 137行static inline char * zend_memnstr(char *haystack, char *needle, int needle_len, char *end)zend_memnstr这个函数比较查找字串的方法十分巧妙,简洁而有力。 找到位置后 p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp); add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1); 用add_next_index_stringl这个函数把结果存入return_value , return_value 也是个zval类型的变量。 它或者是个全局的变量,因为我没有在PHP_FUNCTION(explode)这个函数里发现它初始化的地方。 add_next_index_stringl这个函数在/Zend/zend_API.c里1144行。 麻烦了,在这个函数里又碰到了几个函数,我靠ZEND_API int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate) { zval *tmp; MAKE_STD_ZVAL(tmp); ZVAL_STRINGL(tmp, str, length, duplicate); return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL); }zend_hash_next_index_insert在/Zend/zend_hash.h里定义 116行#define zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \ _zend_hash_index_update_or_next_insert(ht, 0, pData, nDataSize, pDest, HASH_NEXT_INSERT ZEND_FILE_LINE_CC)打开/Zend/zend_hash.c 终于找到了一个复杂的函数,看起来对我们来说应该也是终结的函数了。 342行ZEND_API int _zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, void *pData, uint nDataSize, voidzval有个属性就是HashTable的。 HashTable在zend_hash.h里定义 60行 未完待续
相关文章: