这篇文章主要介绍了深入服务器端编程语言(专业超文本预处理器的缩写)内核之数组中的服务器端编程语言(Professional Hypertext Preprocessor的缩写)的相关资料,需要的朋友可以参考下
先给大家介绍数组中的服务器端编程语言(Professional Hypertext Preprocessor的缩写)函数基本知识热热身。
定义和用法
in_array()函数在数组中搜索给定的值。
语法
数组中(值,数组,类型)
参数
描述
价值
必需。规定要在数组搜索的值。
排列
必需。规定要搜索的数组。
类型
可选。如果设置该参数为没错,则检查搜索的数据与数组的值的类型是否相同。
说明
如果给定的值价值存在于数组排列中则返回没错。如果第三个参数设置为没错,函数只有在元素存在于数组中且数据类型与给定值相同时才返回没错。
如果没有在数组中找到参数,函数返回错误。
注释:如果价值参数是字符串,且类型参数设置为没错,则搜索区分大小写。
无意中看到一段代码
?服务器端编程语言(专业超文本预处理器的缩写)
1800美元
$ x=array();
for($ j=0;50000美元;$j ){
$ x[]= { $ j } ;
}
for($ I=0;30000美元;$i ){
if(in _ array $ y,$x)){
继续;
}
}
测试了一下
[root @ dev tmp]# time PHP b.php
真正的0m9.517s
用户0m4.486s
sys 0m0.015s
竟然需要9s
在数组中是这个样子的
复制代码代码如下:
布尔输入数组(混合$针,数组$haystack [,bool $strict=FALSE ])
在干草堆中搜索针,如果没有设置严格的则使用宽松的比较。
needle
待搜索的值。如果针是字符串,则比较是区分大小写的。
haystack
这个数组。
strict
如果第三个参数严格的的值为真实的则in_array()函数还会检查针的类型是否和干草堆中的相同。
那么我看一下源代码
第一步在扩展/标准/阵列。c文件中
/* }}} */
/* {{{原始布尔值in_array(混合针,数组草堆[,布尔严格])
检查数组中是否存在给定值*/
PHP_FUNCTION(in_array)
{
PHP _ search _ array(INTERNAL _ FUNCTION _ PARAM _ PASSTHRU,0);
}
/* }}} */
/* { { { proto mixed array _ search(mixed need,array草堆[,bool strict])
在数组中搜索给定值,如果搜索成功,则返回相应的键*/
PHP _函数(数组_搜索)
{
PHP _ search _ array(INTERNAL _ FUNCTION _ PARAM _ PASSTHRU,1);
}
/* }}} */
顺便看到了数组_搜索,原来和在数组中的内部实现基本一致
其中函数的参数 在./zend.h中
# define INTERNAL _ FUNCTION _ PARAM _ PASSTHRU ht,return_value,return_value_ptr,this_ptr,return_value_used TSRMLS_CC
第二步在扩展/标准/阵列。c文件中查看php _搜索_数组原型
/* void php_search_array(内部函数_参数,int行为)
* 0=返回布尔值
* 1=返回键
*/
静态void PHP _ search _ array(INTERNAL _ FUNCTION _ PARAMETERS,int behavior) /* {{{ */
{
zval *值,/*要检查的值*/
*数组,/*要检入的数组*/
* *条目,/*指向数组条目的指针*/
res/*比较结果*/
散列位置位置/*哈希迭代器*/
Zend _ bool strict=0;/*是否严格比较*/
ulong数字密钥
uint字符串关键字长度
字符*字符串_关键字
int (*is_equal_func)(zval *,zval *,zval * TSR mls _ DC)=is _ equal _ func;
if(ZEND _ parse _ parameters(ZEND _ NUM _ ARGS()TSR mls _ CC, za|b ,value,array,strict)==FAILURE) {
返回;
}
如果(严格){
is _ equal _ func=is _ identity _ func;
}
Zend _ hash _ internal _ pointer _ reset _ ex(Z _ ARRVAL _ P(array),pos);
while(Zend _ hash _ get _ current _ data _ ex(Z _ ARRVAL _ P(array),(void **)entry,pos)==SUCCESS) {
is_equal_func(res,value,* entry TSR mls _ CC);
if (Z_LVAL(res)) {
if (behavior==0) {
返回真
}否则{
/*返回当前密钥*/
switch(Zend _ hash _ get _ current _ key _ ex(Z _ ARRVAL _ P(array),string_key,str_key_len,num_key,0,pos)) {
案例哈希关键字字符串:
RETURN_STRINGL(string_key,str_key_len - 1,1);
打破;
案例哈希关键字长度:
RETURN _ LONG(num _ key);
打破;
}
}
}
Zend _ hash _ move _ forward _ ex(Z _ ARRVAL _ P(array),pos);
}
返回_假
}
/* }}} */
/* {{{原始布尔值in_array(混合针,数组草堆[,布尔严格])
检查数组中是否存在给定值*/
我们发现严格的这个值的不同有两种比较方式,看一下两个函数的不同之处
is_identical_function 检查类型是否相同
ZEND _ API int is _ identity _ function(zval * result,zval *op1,zval *op2 TSRMLS_DC) /* {{{ */
{
z _ TYPE _ P(result)=IS _ BOOL;
if (Z_TYPE_P(op1)!=Z_TYPE_P(op2)) {
zlval P(结果)=0;
返回成功;
}
开关(Z_TYPE_P(op1)) {
案例为空:
zlval P(结果)=1;
打破;
case IS_BOOL:
案例是_LONG:
案例是_资源:
zlval P(结果)=(Z _ LVAL _ P(op1)==Z _ LVAL _ P(op2));
打破;
案例是_DOUBLE:
zlval P(结果)=(Z _ DVAL _ P(op1)==Z _ DVAL _ P(op2);
打破;
案例是_字符串:
Z _ LVAL _ P(result)=((Z _ STRLEN _ P(op1)==Z _ STRLEN _ P(op2))
(!memcmp(Z_STRVAL_P(op1),Z_STRVAL_P(op2),Z _ STRLEN _ P(op1));
打破;
案例是_数组:
Z _ LVAL _ P(result)=(Z _ ARRVAL _ P(op1)==Z _ ARRVAL _ P(op2)
Zend _ hash _ compare(Z _ arr val _ P(op1),Z_ARRVAL_P(op2),(compare _ func _ t)hash _ zval _ identity _ function,1 TSR mls _ CC)==0);
打破;
案例是_对象:
if(Z _ OBJ _ HT _ P(op1)==Z _ OBJ _ HT _ P(op2)){
Z _ LVAL _ P(结果)=(Z _ OBJ _句柄_ P(op1)==Z _ OBJ _句柄_ P(op2));
}否则{
zlval P(结果)=0;
}
打破;
默认值:
zlval P(结果)=0;
返回失败;
}
返回成功;
}
/* }}} */
is_equal_function 不检查类型是否相同,所以需要隐式转换
ZEND _ API int is _ equal _ function(zval * result,zval *op1,zval *op2 TSRMLS_DC) /* {{{ */
{
if (compare_function(result,op1,op2 TSRMLS_CC)==FAILURE) {
返回失败;
}
ZVAL_BOOL(结果,(Z_LVAL_P(结果)==0));
返回成功;
}
/* }}} */
==》比较_功能
ZEND _ API int compare _ function(zval * result,zval *op1,zval *op2 TSRMLS_DC) /* {{{ */
{
内部ret
int converted=0;
zval op1_copy,op2 _ copy
zval * op _ free
while (1) {
开关(类型对(Z类型P(op1),Z类型P(op2))) {
案例类型对(IS_LONG,IS_LONG):
ZVAL_LONG(结果,Z_LVAL_P(op1)Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)Z_LVAL_P(op2)?-1:0));
返回成功;
案例类型对(IS_DOUBLE,IS_LONG):
DVAL机场(结果)=Z _ DVAL _ P(op1)-(double)Z _ LVAL _ P(op2);
ZVAL_LONG(result,ZEND _ NORMALIZE _ BOOL(Z _ DVAL _ P(result)));
返回成功;
case TYPE_PAIR(IS_LONG,IS_DOUBLE):
DVAL机场(结果)=(double)Z _ LVAL _ P(op1)-Z _ DVAL _ P(op2);
ZVAL_LONG(result,ZEND _ NORMALIZE _ BOOL(Z _ DVAL _ P(result)));
返回成功;
案例类型对(IS_DOUBLE,IS_DOUBLE):
if(Z _ DVAL _ P(op1)==Z _ DVAL _ P(op2)){
ZVAL_LONG(结果,0);
}否则{
DVAL机场(结果)=Z _ DVAL _ P(op1)-Z _ DVAL _ P(op2);
ZVAL_LONG(result,ZEND _ NORMALIZE _ BOOL(Z _ DVAL _ P(result)));
}
返回成功;
案例类型对(IS_ARRAY,IS_ARRAY):
zend_compare_arrays(result,op1,op2 TSR mls _ CC);
返回成功;
案例类型对(IS_NULL,IS_NULL):
ZVAL_LONG(结果,0);
返回成功;
案例类型对(IS_NULL,IS_BOOL):
ZVAL_LONG(结果,Z_LVAL_P(op2)?-1 : 0);
返回成功;
案例类型对(IS_BOOL,IS_NULL):
ZVAL_LONG(结果,Z_LVAL_P(op1)?1 : 0);
返回成功;
案例类型对(IS_BOOL,IS_BOOL):
ZVAL_LONG(result,ZEND _ NORMALIZE _ BOOL(Z _ LVAL _ P(op1)-Z _ LVAL _ P(op2)));
返回成功;
案例类型对(IS_STRING,IS_STRING):
zendi_smart_strcmp(result,op1,op2);
返回成功;
案例类型对(IS_NULL,IS_STRING):
ZVAL_LONG(result,zend_binary_strcmp(,0,Z_STRVAL_P(op2),Z _ STRLEN _ P(op2)));
返回成功;
案例类型对(IS_STRING,IS_NULL):
ZVAL_LONG(result,Zend _ binary _ strcmp(Z _ STRVAL _ P(op1),Z_STRLEN_P(op1),,0));
返回成功;
案例类型对(IS_OBJECT,IS_NULL):
ZVAL_LONG(结果,1);
返回成功;
案例类型对(IS_NULL,IS_OBJECT):
ZVAL_LONG(结果,-1);
返回成功;
案例类型对(是对象,是对象):
/*如果两个对象共享同一个比较处理程序,则使用是*/
如果(OBJ)处理器_P(op1,比较_对象)==Z _ OBJ _处理器_P(op2,比较_对象)){
如果(OBJ)句柄_ P(op1)==Z _ OBJ _句柄_P(op2)) {
/*对象句柄相同,显然这是同一个对象*/
ZVAL_LONG(结果,0);
返回成功;
}
ZVAL_LONG(结果,Z _ OBJ _ HT _ P(op1)-比较_对象(op1,op2 TSR mls _ CC));
返回成功;
}
/*故意中断丢失*/
默认值:
if (Z_TYPE_P(op1)==IS_OBJECT) {
if (Z_OBJ_HT_P(op1)-get) {
op _ free=Z _ OBJ _ HT _ P(op1)-get(op1 TSR mls _ CC);
ret=compare_function(result,op_free,op2 TSR mls _ CC);
Zend _ free _ obj _ get _ result(op _ free TSR mls _ CC);
返回浸水使柔软
} else if (Z_TYPE_P(op2)!=IS _ OBJECT Z _ OBJ _ HT _ P(op1)-cast _ OBJECT){
ALLOC _ INIT _ ZVAL(op _ free);
if(Z _ OBJ _ HT _ P(op1)-cast _ object(op1,op_free,Z _ TYPE _ P(op2)TSR mls _ CC)==失败){
ZVAL_LONG(结果,1);
Zend _ free _ obj _ get _ result(op _ free TSR mls _ CC);
返回成功;
}
ret=compare_function(result,op_free,op2 TSR mls _ CC);
Zend _ free _ obj _ get _ result(op _ free TSR mls _ CC);
返回浸水使柔软
}
}
if (Z_TYPE_P(op2)==IS_OBJECT) {
if (Z_OBJ_HT_P(op2)-get) {
op _ free=Z _ OBJ _ HT _ P(op2)-get(op2 TSR mls _ CC);
ret=compare_function(result,op1,op _ free TSR mls _ CC);
Zend _ free _ obj _ get _ result(op _ free TSR mls _ CC);
返回浸水使柔软
} else if (Z_TYPE_P(op1)!=IS _ OBJECT Z _ OBJ _ HT _ P(op2)-cast _ OBJECT){
ALLOC _ INIT _ ZVAL(op _ free);
if(Z _ OBJ _ HT _ P(op2)-cast _ object(op2,op_free,Z _ TYPE _ P(op1)TSR mls _ CC)==失败){
ZVAL_LONG(结果,-1);
Zend _ free _ obj _ get _ result(op _ free TSR mls _ CC);
返回成功;
}
ret=compare_function(result,op1,op _ free TSR mls _ CC);
Zend _ free _ obj _ get _ result(op _ free TSR mls _ CC);
返回浸水使柔软
} else if(Z _ TYPE _ P(op1)==IS _ OBJECT){
ZVAL_LONG(结果,1);
返回成功;
}
}
如果(!已转换){
if (Z_TYPE_P(op1)==IS_NULL) {
zendi_convert_to_boolean(op2,op2_copy,result);
ZVAL_LONG(结果,Z_LVAL_P(op2)?-1 : 0);
返回成功;
} else if(Z _ TYPE _ P(op2)==IS _ NULL){
zendi_convert_to_boolean(op1,op1_copy,result);
ZVAL_LONG(结果,Z_LVAL_P(op1)?1 : 0);
返回成功;
} else if(Z _ TYPE _ P(op1)==IS _ BOOL){
zendi_convert_to_boolean(op2,op2_copy,result);
ZVAL_LONG(result,ZEND _ NORMALIZE _ BOOL(Z _ LVAL _ P(op1)-Z _ LVAL _ P(op2)));
返回成功;
} else if(Z _ TYPE _ P(op2)==IS _ BOOL){
zendi_convert_to_boolean(op1,op1_copy,result);
ZVAL_LONG(result,ZEND _ NORMALIZE _ BOOL(Z _ LVAL _ P(op1)-Z _ LVAL _ P(op2)));
返回成功;
}否则{
zendi _ convert _ scalar _ to _ number(op1,op1_copy,result);
zendi _ convert _ scalar _ to _ number(op2,op2_copy,result);
converted=1;
}
} else if(Z _ TYPE _ P(op1)==IS _ ARRAY){
ZVAL_LONG(结果,1);
返回成功;
} else if(Z _ TYPE _ P(op2)==IS _ ARRAY){
ZVAL_LONG(结果,-1);
返回成功;
} else if(Z _ TYPE _ P(op1)==IS _ OBJECT){
ZVAL_LONG(结果,1);
返回成功;
} else if(Z _ TYPE _ P(op2)==IS _ OBJECT){
ZVAL_LONG(结果,-1);
返回成功;
}否则{
ZVAL_LONG(结果,0);
返回失败;
}
}
}
}
/* }}} */