PHP array_keys如何搜索值?
示例:
$array2 = array("xyz", "xyz", "abc", "abc", "xyz", "xyz", "text", "abc", "text");
print_r(array_keys($array2,"abc"));
因为它们是关键的价值对。我猜PHP是基于哈希进行搜索而不是遍历数组中的每个密钥对。
对此有什么'清晰的想法'?
答案 0 :(得分:5)
在php源代码中,他们逐个遍历每个键和值。 https://github.com/php/php-src/blob/master/ext/standard/array.c#L2439
/* {{{ proto array array_keys(array input [, mixed search_value[, bool strict]])
Return just the keys from the input array, optionally only for the specified search_value */
PHP_FUNCTION(array_keys)
{
zval *input, /* Input array */
*search_value = NULL, /* Value to search for */
**entry, /* An entry in the input array */
res, /* Result of comparison */
*new_val; /* New value */
int add_key; /* Flag to indicate whether a key should be added */
char *string_key; /* String key */
uint string_key_len;
ulong num_key; /* Numeric key */
zend_bool strict = 0; /* do strict comparison */
HashPosition pos;
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zb", &input, &search_value, &strict) == FAILURE) {
return;
}
if (strict) {
is_equal_func = is_identical_function;
}
/* Initialize return array */
if (search_value != NULL) {
array_init(return_value);
} else {
array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input)));
}
add_key = 1;
/* Go through input array and add keys to the return array */
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
if (search_value != NULL) {
is_equal_func(&res, search_value, *entry TSRMLS_CC);
add_key = zval_is_true(&res);
}
if (add_key) {
MAKE_STD_ZVAL(new_val);
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 1, &pos)) {
case HASH_KEY_IS_STRING:
ZVAL_STRINGL(new_val, string_key, string_key_len - 1, 0);
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
break;
case HASH_KEY_IS_LONG:
Z_TYPE_P(new_val) = IS_LONG;
Z_LVAL_P(new_val) = num_key;
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
break;
}
}
zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
}
}
/* }}} */
答案 1 :(得分:1)
请参阅array_keys definition,同时注意解释得非常好的评论:
仅返回输入数组中的键,可选地仅返回指定的search_value
以及后来:
浏览输入数组并将键添加到返回数组
ext/standard/array.c
上的PHP 5.3的定义如下:
2427 /* {{{ proto array array_keys(array input [, mixed search_value[, bool strict]])
2428 Return just the keys from the input array, optionally only for the specified search_value */
2429 PHP_FUNCTION(array_keys)
2430 {
2431 zval *input, /* Input array */
2432 *search_value = NULL, /* Value to search for */
2433 **entry, /* An entry in the input array */
2434 res, /* Result of comparison */
2435 *new_val; /* New value */
2436 int add_key; /* Flag to indicate whether a key should be added */
2437 char *string_key; /* String key */
2438 uint string_key_len;
2439 ulong num_key; /* Numeric key */
2440 zend_bool strict = 0; /* do strict comparison */
2441 HashPosition pos;
2442 int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
2443
2444 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zb", &input, &search_value, &strict) == FAILURE) {
2445 return;
2446 }
2447
2448 if (strict) {
2449 is_equal_func = is_identical_function;
2450 }
2451
2452 /* Initialize return array */
2453 if (search_value != NULL) {
2454 array_init(return_value);
2455 } else {
2456 array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input)));
2457 }
2458 add_key = 1;
2459
2460 /* Go through input array and add keys to the return array */
2461 zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
2462 while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
2463 if (search_value != NULL) {
2464 is_equal_func(&res, search_value, *entry TSRMLS_CC);
2465 add_key = zval_is_true(&res);
2466 }
2467
2468 if (add_key) {
2469 MAKE_STD_ZVAL(new_val);
2470
2471 switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 1, &pos)) {
2472 case HASH_KEY_IS_STRING:
2473 ZVAL_STRINGL(new_val, string_key, string_key_len - 1, 0);
2474 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
2475 break;
2476
2477 case HASH_KEY_IS_LONG:
2478 Z_TYPE_P(new_val) = IS_LONG;
2479 Z_LVAL_P(new_val) = num_key;
2480 zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
2481 break;
2482 }
2483 }
2484
2485 zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
2486 }
2487 }
2488 /* }}} */
array_keys
Docs的PHP手册页上也解释了执行的搜索:
如果指定了可选的search_value,则仅返回该值的键。否则,将返回输入中的所有键。
另请参阅$strict
参数以影响比较值的方式:
确定在搜索过程中是否应使用严格比较(===)。
两种类型的比较==(等于)和===(相同)是documented as well。
答案 2 :(得分:0)
我怀疑这并不容易: