当前位置: 首页 > 后端技术 > PHP

PHPstrstr源码分析

时间:2023-03-29 22:28:00 PHP

strstr函数原型源码分析版PHP5.3.291、ext/standard/php_string.hPHP_FUNCTION(strstr);2、ext/standard/string.cPHP_FUNCTION(strstr){zval*needle;炭*干草堆;inthaystack_len;char*found=NULL;字符needle_char[2];长发现偏移量;zend_bool部分=0;如果(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(NULLTSRMLS_CC,E_WARNING,"空分隔符");返回假;}found=php_memnstr(haystack,Z_STRVAL_P(needle),Z_STRLEN_P(needle),haystack+haystack_len);}else{if(php_needle_char(needle,needle_charTSRMLS_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.htypedefstruct_zval_structzval;struct_zval_struct{/*变量信息*/zvalue_valuevalue;/*值*/zend_uintrefcount__gc;zend_uchar类型;/*activetype*/zend_ucharis_ref__gc;};needle是一个可变结构体,对应phpstrstr函数参数mixed$needle1,char*haystackchar*haystacks是字符指针,对应phpstrstr函数参数字符串$haystack2,zend_parse_parametersfile位置Zend/zend_API.cintzend_parse_parameters(intnum_argsTSRMLS_DC,char*type_spec,...);intzend_parse_parameters_ex(intflags,intnum_argsTSRMLS_DC,char*type_spec,...);ZEND_APIintzend_parse_parameters(intnum_argsTSRMLS_DC,char*type_spec,...)/*{{{*/{va_listva;内部更新;RETURN_IF_ZERO_ARGS(num_args,type_spec,0);va_start(va,type_spec);retval=zend_parse_va_args(num_args,type_spec,&va,0TSRMLS_CC);va_end(va);returnretval;}/*}}}*/ZEND_APIintzend_parse_method_parameters(intnum_argsTSRMLS_DC,zval*this_ptr,char*type_spec,...)/*{{{*/{va_listva;内部更新;char*p=type_spec;zval**对象;zend_class_entry*ce;如果(!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,0TSRMLS_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),ceTSRMLS_CC)){zend_error(E_CORE_ERROR,"%s::%s()必须派生自m%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,0TSRMLS_CC);va_end(va);}returnretval;}获取函数调用者传递的参数最简单的方法是使用zend_parse_parameters()函数,zend_parse_parameters()函数的前几个参数可以直接由内核中的宏生成。形式为:ZEND_NUM_ARGS()TSRMLS_CC,注意两者之间有一个空格,但是没有逗号。从名字可以看出,ZEND_NUM_ARGS()代表参数个数。需要传递给的参数zend_parse_parameters()函数是一个格式为优化过的字符串,就像printf的第一个参数一样,最常用的符号如下所示。type_spec为格式化字符串,其常用含义如下:参数表示类型bBooleanlInteger整型dFloatingpoint浮点数sStringstringrResource资源aArray数组oObject实例对象O指定类型的Object实例具体类型ofobjectzNon-specificzvalAnytype~Zzval**typef表示函数或方法的名称,PHP5.1中好像没有...3.if(Z_TYPE_P(needle)==IS_STRING)Z_TYPE_P文件位置:Zend/zend_operators.h#defineZ_TYPE_P(zval_p)Z_TYPE(*zval_p)#defineZ_TYPE(zval)(zval).type4,if(!Z_STRLEN_P(needle)){Z_STRLEN_P文件位置:Zend/zend_operators.h#定义Z_STRLEN_P(zval_p)Z_STRLEN(*zval_p)#defineZ_STRLEN(zval)(zval).value.str.len5、php_memnstr(haystack,Z_STRVAL_P(needle),Z_STRLEN_P(needle),haystack+haystack_len);文件位置:main/php.h#definephp_memnstrzend_memnstr文件位置:Zend/zend_operators.hstaticinlinechar*zend_memnstr(char*haystack,char*needle,intneedle_len,char*end){char*p=haystack;charne=needle[needle_len-1];如果(needle_len==1){return(char*)memchr(p,*needle,(end-p));}if(needle_len>end-haystack){返回NULL;}结束-=needle_len;while(p<=end){if((p=(char*)memchr(p,*needle,(end-p+1)))&&ne==p[needle_len-1]){if(!memcmp(针,p,needle_len-1)){返回p;}}if(p==NULL){返回NULL;}p++;}returnNULL;}核心函数memchrmemcmpzend_memnstr代码分析示例:strstr('helloword!','world');zend_memnstr(char*haystack,char*needle,intneedle_len,char*end)char*haystack="helloword!";char*needle="world";intneedle_len=strlen(needle);char*end=haystack+strlen(haystack)尾指针char*p=haystack字符开始元素地址charne=needle[needle_len-1]singleneedle末尾的字符dend-=needle_len//Initial:4231185Subtracted: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==worldreturnp引用https://www.kancloud.cn/fage/...https://www.runoob.com/cprogr...http://t.zoukankan.com/string...