This article mainly introduces the relevant information about phpinarray in php kernel. For more information about php in array functions, see below.
Definition and usage
The in_array () function searches for the given value in the array.
Syntax
In_array (value, array, type)
Parameters |
Description |
Value |
Required. Specifies the value to be searched in the array. |
Array |
Required. Specifies the array to be searched. |
Type |
Optional. If this parameter is set to true, check whether the data to be searched is of the same type as the value of the array. |
Description
Returns true if the given value exists in the array. If the third parameter is set to true, the function returns true only when the element exists in the array and the data type is the same as the given value.
If no parameter is found in the array, the function returns false.
Note: If the value parameter is a string and the type parameter is set to true, the search area is case sensitive.
Inadvertently seeing a piece of code
<?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; } }
Tested
[Root @ dev tmp] # time php B. php
Real 0m9. 517 s
User 0m4. 486 s
Sys 0m0. 015 s
It takes 9 s.
In_array looks like this
The Code is as follows:
Bool in_array (mixed $ needle, array $ haystack [, bool $ strict = FALSE])
Search for needle in haystack. If strict is not set, use loose comparison.
Needle
The value to be searched. If the needle is a string, the comparison is case sensitive.
Haystack
This array.
Strict
If the value of the third strict parameter is TRUE, the in_array () function checks whether the needle type is the same as that in haystack.
So let me take a look at the source code
The first step is in the ext/standard/array. c file.
/* }}} */ /* {{{ 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, array haystack [, 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); } /* }}} */
By the way, we can see that array_search is basically consistent with the internal implementation of in_array.
The function parameters are in./zend. h.
# Define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, return_value_ptr, this_ptr, return_value_used TSRMLS_CC
Step 2 view the php_search_array prototype in the ext/standard/array. c file
/* 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, 0, &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, array haystack [, bool strict]) Checks if the given value exists in the array */
We found that there are two comparison methods for the value of strict. Let's take a look at the differences between the two functions.
Is_identical_function check whether the types are the same
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 does not check whether the types are the same, so implicit conversion is required.
ZEND_API int is_equal_function(zval *result, zval *op1, 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_functionZEND_API int compare_function(zval *result, zval *op1, 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)
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, op_free, 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, op_free, 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, op1, 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, op_free, 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, op1, 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, result); ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0); return SUCCESS; } 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))); return SUCCESS; } 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))); return SUCCESS; } else { 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(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; } } } } /* }}} */