diff --git a/ext/standard/array.c b/ext/standard/array.c index f8dd7d891dd39..75038830e013c 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4385,6 +4385,39 @@ PHP_FUNCTION(array_keys) } /* }}} */ +/* {{{ */ +PHP_FUNCTION(is_assoc_array) +{ + zval *arr; + zend_array *ht; + zend_ulong idx, expected = 0; + zend_string *key; + + ZEND_PARSE_PARAMETERS_START(1,1) + Z_PARAM_ARRAY(arr) + ZEND_PARSE_PARAMETERS_END(); + + ht = Z_ARRVAL_P(arr); + + if (zend_hash_num_elements(ht) == 0) { + RETURN_FALSE; + } + + if(!HT_IS_PACKED(ht)){ + RETURN_TRUE; + } + + ZEND_HASH_FOREACH_KEY(ht, idx, key) { + if (key != NULL || idx != expected++) { + RETURN_TRUE; /* associative */ + } + } ZEND_HASH_FOREACH_END(); + + RETURN_FALSE; + +} +/* }}} */ + /* {{{ Get the key of the first element of the array */ PHP_FUNCTION(array_key_first) { diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 6fa0d47c7bd7f..f1260f525ede5 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1696,6 +1696,11 @@ function array_replace_recursive(array $array, array ...$replacements): array {} */ function array_keys(array $array, mixed $filter_value = UNKNOWN, bool $strict = false): array {} +/** + * @compile-time-eval + */ +function is_assoc_array(array $array): bool {} + /** * @compile-time-eval */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index e467710f72f91..5c026a2628c02 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 8d1c2a735f412f8571675c6b025c3a418b68fb65 + * Stub hash: 08db3bddcb9566d062b02c7d21e5bec5a5c61f23 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -236,6 +236,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_keys, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, strict, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_is_assoc_array, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_array_key_first, 0, 1, MAY_BE_LONG|MAY_BE_STRING|MAY_BE_NULL) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -387,9 +391,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_combine, 0, 2, IS_ARRAY, 0 ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_is_list, 0, 1, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) -ZEND_END_ARG_INFO() +#define arginfo_array_is_list arginfo_is_assoc_array ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_base64_encode, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) @@ -2366,6 +2368,7 @@ ZEND_FUNCTION(array_merge_recursive); ZEND_FUNCTION(array_replace); ZEND_FUNCTION(array_replace_recursive); ZEND_FUNCTION(array_keys); +ZEND_FUNCTION(is_assoc_array); ZEND_FUNCTION(array_key_first); ZEND_FUNCTION(array_key_last); ZEND_FUNCTION(array_first); @@ -2960,6 +2963,7 @@ static const zend_function_entry ext_functions[] = { ZEND_RAW_FENTRY("array_replace", zif_array_replace, arginfo_array_replace, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_replace_recursive", zif_array_replace_recursive, arginfo_array_replace_recursive, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_keys", zif_array_keys, arginfo_array_keys, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) + ZEND_RAW_FENTRY("is_assoc_array", zif_is_assoc_array, arginfo_is_assoc_array, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_key_first", zif_array_key_first, arginfo_array_key_first, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_key_last", zif_array_key_last, arginfo_array_key_last, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_first", zif_array_first, arginfo_array_first, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index 9e6fb0def4472..6755804c2aa6a 100644 --- a/ext/standard/basic_functions_decl.h +++ b/ext/standard/basic_functions_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 8d1c2a735f412f8571675c6b025c3a418b68fb65 */ + * Stub hash: 08db3bddcb9566d062b02c7d21e5bec5a5c61f23 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_8d1c2a735f412f8571675c6b025c3a418b68fb65_H -#define ZEND_BASIC_FUNCTIONS_DECL_8d1c2a735f412f8571675c6b025c3a418b68fb65_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_08db3bddcb9566d062b02c7d21e5bec5a5c61f23_H +#define ZEND_BASIC_FUNCTIONS_DECL_08db3bddcb9566d062b02c7d21e5bec5a5c61f23_H typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_HalfAwayFromZero = 1, @@ -15,4 +15,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_8d1c2a735f412f8571675c6b025c3a418b68fb65_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_08db3bddcb9566d062b02c7d21e5bec5a5c61f23_H */ diff --git a/ext/standard/tests/array/is_assoc_array.phpt b/ext/standard/tests/array/is_assoc_array.phpt new file mode 100644 index 0000000000000..82b0c11c3cc81 --- /dev/null +++ b/ext/standard/tests/array/is_assoc_array.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test is_assoc_array() behavior +--FILE-- + 'a', 0 => 'b'])); +echo "2. "; var_dump(is_assoc_array([1 => 'a', 0 => 'b'])); +echo "3. "; var_dump(is_assoc_array([1 => 'a', 2 => 'b'])); +echo "4. "; var_dump(is_assoc_array([0 => 'a', 1 => 'b'])); +echo "5. "; var_dump(is_assoc_array(['a', 'b'])); + +echo "6. "; var_dump(is_assoc_array([])); +echo "7. "; var_dump(is_assoc_array([1, 2, 3])); +echo "8. "; var_dump(is_assoc_array(['foo', 2, 3])); +echo "9. "; var_dump(is_assoc_array([0 => 'foo', 'bar'])); + +echo "10. "; var_dump(is_assoc_array([1 => 'foo', 'bar'])); +echo "11. "; var_dump(is_assoc_array([0 => 'foo', 'bar' => 'baz'])); +echo "12. "; var_dump(is_assoc_array([0 => 'foo', 2 => 'bar'])); +echo "13. "; var_dump(is_assoc_array(['foo' => 'bar', 'baz' => 'qux'])); + +?> +--EXPECT-- +1. bool(true) +2. bool(true) +3. bool(true) +4. bool(false) +5. bool(false) +6. bool(false) +7. bool(false) +8. bool(false) +9. bool(false) +10. bool(true) +11. bool(true) +12. bool(true) +13. bool(true)