一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

PHP strstr函数原型源码分析

时间:2026-09-21 18:10:01 编辑:袖梨 来源:一聚教程网

这篇文章主要为大家介绍了PHP strstr函数原型源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

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是格式化字符串,其常见的含义如下:参数代表着的类型bBooleanlInteger 整型dFloating point 浮点型sString 字符串rResource 资源aArray 数组oObject instance 对象OObject instance of a specified type 特定类型的对象zNon-specific zval 任意类型~Zzval**类型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.hstatic 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 尾部单个字符 dend -= 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] == dif (!memcmp(needle, p, needle_len-1)) //world == worldreturn p

引用

https://www.*run*o*ob.com/cprogramming/c-function-memcmp.html

https://www.j***b51.net/article/77667.htm

https://www.j***b51.net/article/210253.htm

热门栏目