strstr
函数原型
源码分析 版本php5.3.29
1、ext/standard/php_string.h
php_function(strstr);
2、ext/standard/string.c
php_function(strstr) { zval *needle; char *haystack; int haystack_len; char *found = null; char needle_char[2]; long found_offset; zend_bool part = 0; if (zend_parse_parameters(zend_num_args() tsrmls_cc, "sz|b", &haystack, &haystack_len, &needle, &part) == failure) { return; } if (z_type_p(needle) == is_string) { if (!z_strlen_p(needle)) { php_error_docref(null tsrmls_cc, e_warning, "empty delimiter"); return_false; } found = php_memnstr(haystack, z_strval_p(needle), z_strlen_p(needle), haystack + haystack_len); } else { if (php_needle_char(needle, needle_char tsrmls_cc) != success) { return_false; } needle_char[1] = 0; found = php_memnstr(haystack, needle_char, 1, haystack + haystack_len); } if (found) { found_offset = found - haystack; if (part) { return_stringl(haystack, found_offset, 1); } else { return_stringl(found, haystack_len - found_offset, 1); } } return_false; }
zval *needle
文件位置 zend/zend.h
typedef struct _zval_struct zval; struct _zval_struct { /* variable information */ zvalue_value value; /* value */ zend_uint refcount__gc; zend_uchar type; /* active type */ zend_uchar is_ref__gc; };
needle是一个变量结构体,对应php strstr 函数参数 mixed $needle
1、char *haystack
char *haystack s是一个字符指针,对应 php strstr函数参数 string $haystack
2、zend_parse_parameters
文件位置 zend/zend_api.c
int zend_parse_parameters(int num_args tsrmls_dc, char *type_spec, ...); int zend_parse_parameters_ex(int flags, int num_args tsrmls_dc, char *type_spec, ...); zend_api int zend_parse_parameters(int num_args tsrmls_dc, char *type_spec, ...) /* {{{ */ { va_list va; int retval; return_if_zero_args(num_args, type_spec, 0); va_start(va, type_spec); retval = zend_parse_va_args(num_args, type_spec, &va, 0 tsrmls_cc); va_end(va); return retval; } /* }}} */ zend_api int zend_parse_method_parameters(int num_args tsrmls_dc, zval *this_ptr, char *type_spec, ...) /* {{{ */ { va_list va; int retval; char *p = type_spec; zval **object; zend_class_entry *ce; if (!this_ptr) { return_if_zero_args(num_args, p, 0); va_start(va, type_spec); retval = zend_parse_va_args(num_args, type_spec, &va, 0 tsrmls_cc); va_end(va); } else { p++; return_if_zero_args(num_args, p, 0); va_start(va, type_spec); object = va_arg(va, zval **); ce = va_arg(va, zend_class_entry *); *object = this_ptr; if (ce && !instanceof_function(z_objce_p(this_ptr), ce tsrmls_cc)) { zend_error(e_core_error, "%s::%s() must be derived from %s::%s", ce->name, get_active_function_name(tsrmls_c), z_objce_p(this_ptr)->name, get_active_function_name(tsrmls_c)); } retval = zend_parse_va_args(num_args, p, &va, 0 tsrmls_cc); va_end(va); } return retval; }
最简单的获取函数调用者传递过来的参数便是使用zend_parse_parameters()函数。
zend_parse_parameters() 函数的前几个参数我们直接用内核里宏来生成便可以了,形式为:zend_num_args() tsrmls_cc,注意两者之间有个空格,但是没有逗号。从名字可以看出,zend_num_args()代表着参数的个数。
紧接着需要传递给zend_parse_parameters()函数的参数是一个用于格式化的字符串,就像printf的第一个参数一样。下面表示了最常用的几个符号。
type_spec是格式化字符串,其常见的含义如下:
参数 代表着的类型
b boolean
l integer 整型
d floating point 浮点型
s string 字符串
r resource 资源
a array 数组
o object instance 对象
o object instance of a specified type 特定类型的对象
z non-specific zval 任意类型~
z zval**类型
f 表示函数、方法名称,php5.1里貌似木有... ...
3、if (z_type_p(needle) == is_string)
z_type_p 文件位置:zend/zend_operators.h #define z_type_p(zval_p) z_type(*zval_p) #define z_type(zval) (zval).type
4、if (!z_strlen_p(needle)) {
z_strlen_p 文件位置:zend/zend_operators.h #define z_strlen_p(zval_p) z_strlen(*zval_p) #define z_strlen(zval) (zval).value.str.len
5、php_memnstr(haystack, z_strval_p(needle), z_strlen_p(needle), haystack + haystack_len);
文件位置:main/php.h #define php_memnstr zend_memnstr 文件位置:zend/zend_operators.h static inline char * zend_memnstr(char *haystack, char *needle, int needle_len, char *end) { char *p = haystack; char ne = needle[needle_len-1]; if (needle_len == 1) { return (char *)memchr(p, *needle, (end-p)); } if (needle_len > end-haystack) { return null; } end -= needle_len; while (p <= end) { if ((p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) { if (!memcmp(needle, p, needle_len-1)) { return p; } } if (p == null) { return null; } p++; } return null; }
核心函数
memchr memcmp
zend_memnstr 代码分析
举例:
strstr('hello word!','world');
zend_memnstr(char *haystack, char *needle, int needle_len, char *end) char *haystack = "hello word!"; char *needle = "world"; int needle_len = strlen(needle); char *end = haystack + strlen(haystack) 尾部指针 char *p = haystack 字符首元素地址 char ne = needle[needle_len-1] needle 尾部单个字符 d end -= needle_len // 初始:4231185 减后:4231180 (p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1] p = (char *)memchr(p, *needle, (end-p+1) // char *p = "world!"; ne == p[needle_len-1] // p[needle_len-1] == d if (!memcmp(needle, p, needle_len-1)) //world == world return p
引用
https://www.runoob.com/cprogramming/c-function-memcmp.html
以上就是php strstr源码分析的详细内容,更多关于php strstr的资料请关注代码网其它相关文章!
发表评论