深入php内核之php in array
《深入php内核之php in array》要点: 先给年夜家介绍php in array函数基本知识热热身.PHP实战 界说和用法PHP实战 in_array() 函数在数组中搜刮给定的值.PHP实战 语法 ?阐明 如果给定的值 value 存在于数组 array 中则返回 true.如果第三个参数设置为 true,函数只有在元素存在于数组中且数据类型与给定值雷同时才返回 true. 假如没有在数组中找到参数,函数返回 false.PHP实战 注释:如果 value 参数是字符串,且 type 参数设置为 true,则搜索区分年夜小写.PHP实战 无心中看到一段代码PHP实战 <必修php $y="1800"; $x = array(); for($j=0;$j<50000;$j++){ $x[]= "{$j}"; } for($i=0;$i<30000;$i++){ if(in_array($y,$x)){ continue; } } 测试了一下PHP实战 [root@dev tmp]# time php b.php 竟然必要9sPHP实战 in_array是这个样子的PHP实战
代码如下:
bool in_array ( mixed $needle,array $haystack [,bool $strict = FALSE ] ) 在 haystack 中搜索 needle,如果没有设置 strict 则使用宽松的比拟.PHP实战 needlePHP实战 待搜索的值.如果 needle 是字符串,则比拟是区分大小写的.PHP实战 haystackPHP实战 这个数组.PHP实战 strictPHP实战 如果第三个参数 strict 的值为 TRUE 则 in_array() 函数还会反省 needle 的类型是否和 haystack 中的相同.PHP实战 那么我看一下源代码PHP实战 第一步 在ext/standard/array.c 文件中PHP实战 /* }}} */ /* {{{ proto bool in_array(mixed needle,array haystack [,bool strict]) Checks if the given value exists in the array */ PHP_FUNCTION(in_array) { php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU,0); } /* }}} */ /* {{{ proto mixed array_search(mixed needle,bool strict]) Searches the array for a given value and returns the corresponding key if successful */ PHP_FUNCTION(array_search) { php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU,1); } /* }}} */ 顺便看到了array_search,本来和in_array的内部实现基本一致PHP实战 此中函数的参数 在./zend.h中PHP实战 #define INTERNAL_FUNCTION_PARAM_PASSTHRU ht,return_value,return_value_ptr,this_ptr,return_value_used TSRMLS_CCPHP实战 第二步 在ext/standard/array.c 文件中 查看php_search_array原型PHP实战 /* void php_search_array(INTERNAL_FUNCTION_PARAMETERS,int behavior) * 0 = return boolean * 1 = return key */ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS,int behavior) /* {{{ */ { zval *value,/* value to check for */ *array,/* array to check in */ **entry,/* pointer to array entry */ res; /* comparison result */ HashPosition pos; /* hash iterator */ zend_bool strict = 0; /* strict comparison or not */ ulong num_key; uint str_key_len; char *string_key; int (*is_equal_func)(zval *,zval *,zval * TSRMLS_DC) = is_equal_function; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,"za|b",&value,&array,&strict) == FAILURE) { return; } if (strict) { is_equal_func = is_identical_function; } 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 TSRMLS_CC); if (Z_LVAL(res)) { if (behavior == 0) { RETURN_TRUE; } else { /* Return current key */ switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array),&string_key,&str_key_len,&num_key,&pos)) { case HASH_KEY_IS_STRING: RETURN_STRINGL(string_key,str_key_len - 1,1); break; case HASH_KEY_IS_LONG: RETURN_LONG(num_key); break; } } } zend_hash_move_forward_ex(Z_ARRVAL_P(array),&pos); } RETURN_FALSE; } /* }}} */ /* {{{ proto bool in_array(mixed needle,bool strict]) Checks if the given value exists in the array */ 我们发现 strict? 这个值的不同有两种比拟方式,看一下两个函数的不同之处PHP实战 is_identical_function 反省类型是否相同PHP实战 ZEND_API int is_identical_function(zval *result,zval *op1,zval *op2 TSRMLS_DC) /* {{{ */ { Z_TYPE_P(result) = IS_BOOL; if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { Z_LVAL_P(result) = 0; return SUCCESS; } switch (Z_TYPE_P(op1)) { case IS_NULL: Z_LVAL_P(result) = 1; break; case IS_BOOL: case IS_LONG: case IS_RESOURCE: Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); break; case IS_DOUBLE: Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); break; case IS_STRING: 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)))); break; case IS_ARRAY: Z_LVAL_P(result) = (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) zend_hash_compare(Z_ARRVAL_P(op1),Z_ARRVAL_P(op2),(compare_func_t) hash_zval_identical_function,1 TSRMLS_CC)==0); break; case IS_OBJECT: if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) { Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)); } else { Z_LVAL_P(result) = 0; } break; default: Z_LVAL_P(result) = 0; return FAILURE; } return SUCCESS; } /* }}} */ is_equal_function 不检查类型是否相同,所以必要隐式转换PHP实战 ZEND_API int is_equal_function(zval *result,zval *op2 TSRMLS_DC) /* {{{ */ { if (compare_function(result,op1,op2 TSRMLS_CC) == FAILURE) { return FAILURE; } ZVAL_BOOL(result,(Z_LVAL_P(result) == 0)); return SUCCESS; } /* }}} */ ==》compare_function ZEND_API int compare_function(zval *result,zval *op2 TSRMLS_DC) /* {{{ */ { int ret; int converted = 0; zval op1_copy,op2_copy; zval *op_free; while (1) { switch (TYPE_PAIR(Z_TYPE_P(op1),Z_TYPE_P(op2))) { case TYPE_PAIR(IS_LONG,IS_LONG): ZVAL_LONG(result,Z_LVAL_P(op1)>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; } } } } /* }}} */ 编程之家培训学院每天发布《深入php内核之php in array》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |