php源码研究-explode函数追踪

2006-07-21 bailing
我要把explode函数的功能分离出来
ext/string.c里有函数PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, int limit) 
PHPAPI是什么?这个以后找到了再说
zval是什么?在/Zend/zend.h这个文件里,定义了zval的struct

struct _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, void 

zval有个属性就是HashTable的。
HashTable在zend_hash.h里定义
60行

未完待续
Posted on 2006-07-24 10:23  古代  阅读(1116)  评论(0编辑  收藏  举报