in_array和array_search源码分析
/* in_array和array_search进入的函数是一样的,调用php_search_array传的behavior来标识 */
/* {{{ Checks if the given value exists in the array */ PHP_FUNCTION(in_array) { php_search_array(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ /* {{{ 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); } /* }}} */
/* void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) * 0 = return boolean * 1 = return key */ static inline 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 */ zend_ulong num_idx; zend_string *str_idx; zend_bool strict = 0; /* strict comparison or not */
/* 参数检验 */ ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_ZVAL(value) Z_PARAM_ARRAY(array) Z_PARAM_OPTIONAL Z_PARAM_BOOL(strict) ZEND_PARSE_PARAMETERS_END(); if (strict) { if (Z_TYPE_P(value) == IS_LONG) {
/* 遍历hastTable */ ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(array), num_idx, str_idx, entry) { ZVAL_DEREF(entry); if (Z_TYPE_P(entry) == IS_LONG && Z_LVAL_P(entry) == Z_LVAL_P(value)) { if (behavior == 0) { RETURN_TRUE; } else { if (str_idx) { RETVAL_STR_COPY(str_idx); } else { RETVAL_LONG(num_idx); } return; } } } ZEND_HASH_FOREACH_END(); } else { ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(array), num_idx, str_idx, entry) { ZVAL_DEREF(entry); if (fast_is_identical_function(value, entry)) { if (behavior == 0) { RETURN_TRUE; } else { if (str_idx) { RETVAL_STR_COPY(str_idx); } else { RETVAL_LONG(num_idx); } return; } } } ZEND_HASH_FOREACH_END(); } } else { if (Z_TYPE_P(value) == IS_LONG) { ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(array), num_idx, str_idx, entry) { if (fast_equal_check_long(value, entry)) { if (behavior == 0) { RETURN_TRUE; } else { if (str_idx) { RETVAL_STR_COPY(str_idx); } else { RETVAL_LONG(num_idx); } return; } } } ZEND_HASH_FOREACH_END(); } else if (Z_TYPE_P(value) == IS_STRING) { ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(array), num_idx, str_idx, entry) { if (fast_equal_check_string(value, entry)) { if (behavior == 0) { RETURN_TRUE; } else { if (str_idx) { RETVAL_STR_COPY(str_idx); } else { RETVAL_LONG(num_idx); } return; } } } ZEND_HASH_FOREACH_END(); } else { ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(array), num_idx, str_idx, entry) { if (fast_equal_check_function(value, entry)) { if (behavior == 0) { RETURN_TRUE; } else { if (str_idx) { RETVAL_STR_COPY(str_idx); } else { RETVAL_LONG(num_idx); } return; } } } ZEND_HASH_FOREACH_END(); } } RETURN_FALSE; } /* }}} */