定义和用法
语法 in_array(value,array,type)
搜索的值。搜索的数组。搜索的数据与数组的值的类型是否相同。 |
---|
说明
如果给定的值 value 存在于数组 array 中则返回 true。如果第三个参数设置为 true,函数只有在元素存在于数组中且数据类型与给定值相同时才返回 true。
如果没有在数组中找到参数,函数返回 false。
注释:如果 value 参数是字符串,且 type 参数设置为 true,则搜索区分大小写。
无意中看到一段代码
测试了一下
[root@dev tmp]# time PHP b.PHP real 0m9.517s user 0m4.486s sys 0m0.015s
竟然需要9s
in_array是这个样子的
在 haystack 中搜索 needle,如果没有设置 strict 则使用宽松的比较。
needle
待搜索的值。如果 needle 是字符串,则比较是区分大小写的。
haystack
这个数组。
strict
如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。
那么我看一下源代码
第一步 在ext/standard/array.c 文件中
顺便看到了array_search,原来和in_array的内部实现基本一致
其中函数的参数 在./zend.h中
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht,return_value,return_value_ptr,this_ptr,return_value_used TSRMLS_CC
第二步 在ext/standard/array.c 文件中 查看PHP_search_array原型
我们发现 strict 这个值的不同有两种比较方式,看一下两个函数的不同之处
is_identical_function 检查类型是否相同
is_equal_function 不检查类型是否相同,所以需要隐式转换
<div class="jb51code">
@H_301_90@Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
return SUCCESS;
case TYPE_PAIR(IS_DOUBLE,IS_LONG):
Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
ZVAL_LONG(result,ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
return SUCCESS;
case TYPE_PAIR(IS_LONG,IS_DOUBLE):
Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
ZVAL_LONG(result,ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
return SUCCESS;
case TYPE_PAIR(IS_DOUBLE,IS_DOUBLE):
if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
ZVAL_LONG(result,0);
} else {
Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
ZVAL_LONG(result,ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
}
return SUCCESS;
case TYPE_PAIR(IS_ARRAY,IS_ARRAY):
zend_compare_arrays(result,op2 TSRMLS_CC);
return SUCCESS;
case TYPE_PAIR(IS_NULL,IS_NULL):
ZVAL_LONG(result,0);
return SUCCESS;
case TYPE_PAIR(IS_NULL,IS_BOOL):
ZVAL_LONG(result,Z_LVAL_P(op2) ? -1 : 0);
return SUCCESS;
case TYPE_PAIR(IS_BOOL,Z_LVAL_P(op1) ? 1 : 0);
return SUCCESS;
case TYPE_PAIR(IS_BOOL,ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
return SUCCESS;
case TYPE_PAIR(IS_STRING,IS_STRING):
zendi_smart_strcmp(result,op2);
return SUCCESS;
case TYPE_PAIR(IS_NULL,IS_STRING):
ZVAL_LONG(result,zend_binary_strcmp("",Z_STRLEN_P(op2)));
return SUCCESS;
case TYPE_PAIR(IS_STRING,zend_binary_strcmp(Z_STRVAL_P(op1),Z_STRLEN_P(op1),"",0));
return SUCCESS;
case TYPE_PAIR(IS_OBJECT,1);
return SUCCESS;
case TYPE_PAIR(IS_NULL,IS_OBJECT):
ZVAL_LONG(result,-1);
return SUCCESS;
case TYPE_PAIR(IS_OBJECT,IS_OBJECT):
/ If both are objects sharing the same comparision handler then use is /
if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) {
if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
/ object handles are identical,apparently this is the same object /
ZVAL_LONG(result,0);
return SUCCESS;
}
ZVAL_LONG(result,Z_OBJ_HT_P(op1)->compare_objects(op1,op2 TSRMLS_CC));
return SUCCESS;
}
/ break missing intentionally /
default:
if (Z_TYPE_P(op1) == IS_OBJECT) {
if (Z_OBJ_HT_P(op1)->get) {
op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
ret = compare_function(result,op_free,op2 TSRMLS_CC);
zend_free_obj_get_result(op_free TSRMLS_CC);
return ret;
} 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,Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
ZVAL_LONG(result,1);
zend_free_obj_get_result(op_free TSRMLS_CC);
return SUCCESS;
}
ret = compare_function(result,op2 TSRMLS_CC);
zend_free_obj_get_result(op_free TSRMLS_CC);
return ret;
}
}
if (Z_TYPE_P(op2) == IS_OBJECT) {
if (Z_OBJ_HT_P(op2)->get) {
op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
ret = compare_function(result,op_free TSRMLS_CC);
zend_free_obj_get_result(op_free TSRMLS_CC);
return ret;
} 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,Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
ZVAL_LONG(result,-1);
zend_free_obj_get_result(op_free TSRMLS_CC);
return SUCCESS;
}
ret = compare_function(result,op_free TSRMLS_CC);
zend_free_obj_get_result(op_free TSRMLS_CC);
return ret;
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
ZVAL_LONG(result,1);
return SUCCESS;
}
}
if (!converted) {
if (Z_TYPE_P(op1) == IS_NULL) {
zendi_convert_to_boolean(op2,op2_copy,result);
ZVAL_LONG(result,Z_LVAL_P(op2) ? -1 : 0);
return SUCCESS;
} else if (Z_TYPE_P(op2) == IS_NULL) {
zendi_convert_to_boolean(op1,op1_copy,Z_LVAL_P(op1) ? 1 : 0);
return SUCCESS;
} else if (Z_TYPE_P(op1) == IS_BOOL) {
zendi_convert_to_boolean(op2,ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
return SUCCESS;
} else if (Z_TYPE_P(op2) == IS_BOOL) {
zendi_convert_to_boolean(op1,ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
return SUCCESS;
} else {
zendi_convert_scalar_to_number(op1,result);
zendi_convert_scalar_to_number(op2,result);
converted = 1;
}
} else if (Z_TYPE_P(op1)==IS_ARRAY) {
ZVAL_LONG(result,1);
return SUCCESS;
} else if (Z_TYPE_P(op2)==IS_ARRAY) {
ZVAL_LONG(result,-1);
return SUCCESS;
} else if (Z_TYPE_P(op1)==IS_OBJECT) {
ZVAL_LONG(result,1);
return SUCCESS;
} else if (Z_TYPE_P(op2)==IS_OBJECT) {
ZVAL_LONG(result,-1);
return SUCCESS;
} else {
ZVAL_LONG(result,0);
return FAILURE;
}
}
}
}
/ }}} /