From 952d0283d159a694e4b6b8b7d7e0375f73cf1e27 Mon Sep 17 00:00:00 2001 From: Carlos Granados Date: Fri, 3 Apr 2026 08:00:12 +0200 Subject: [PATCH 1/3] Add array_get and array_has functions --- ext/standard/array.c | 108 +++++++++++++++++++++++++ ext/standard/basic_functions.stub.php | 10 +++ ext/standard/basic_functions_arginfo.h | 17 +++- ext/standard/basic_functions_decl.h | 8 +- 4 files changed, 138 insertions(+), 5 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 7aafe6ea0a17..66557d5c6744 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6910,6 +6910,114 @@ PHP_FUNCTION(array_key_exists) } /* }}} */ +/* {{{ Helper function to get a nested value from array using dot notation */ +static zval* array_get_nested(HashTable *ht, const char *key, size_t key_len) +{ + const char *dot; + zval *current; + + /* Find the first dot in the key */ + dot = memchr(key, '.', key_len); + + if (dot == NULL) { + /* No dot found, this is a simple key lookup */ + zend_string *zkey = zend_string_init(key, key_len, 0); + current = zend_symtable_find(ht, zkey); + zend_string_release(zkey); + return current; + } + + /* We have a dot, so we need to recurse */ + size_t segment_len = dot - key; + zend_string *segment = zend_string_init(key, segment_len, 0); + current = zend_symtable_find(ht, segment); + zend_string_release(segment); + + if (current == NULL || Z_TYPE_P(current) != IS_ARRAY) { + return NULL; + } + + /* Recurse into the nested array with the remaining key */ + return array_get_nested(Z_ARRVAL_P(current), dot + 1, key_len - segment_len - 1); +} +/* }}} */ + +/* {{{ Retrieves a value from a deeply nested array using "dot" notation */ +PHP_FUNCTION(array_get) +{ + HashTable *ht; + zval *key = NULL; + zval *default_value = NULL; + zval *result; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_ARRAY_HT(ht) + Z_PARAM_ZVAL_OR_NULL(key) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(default_value) + ZEND_PARSE_PARAMETERS_END(); + + /* If key is null, return the whole array */ + if (key == NULL || Z_TYPE_P(key) == IS_NULL) { + ZVAL_ARR(return_value, zend_array_dup(ht)); + return; + } + + /* Handle string keys with dot notation */ + if (Z_TYPE_P(key) == IS_STRING) { + result = array_get_nested(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)); + + if (result != NULL) { + ZVAL_COPY(return_value, result); + return; + } + } + /* Handle integer keys (no dot notation support) */ + else if (Z_TYPE_P(key) == IS_LONG) { + result = zend_hash_index_find(ht, Z_LVAL_P(key)); + + if (result != NULL) { + ZVAL_COPY(return_value, result); + return; + } + } + + /* Key not found, return default value */ + if (default_value != NULL) { + ZVAL_COPY(return_value, default_value); + } else { + RETVAL_NULL(); + } +} +/* }}} */ + +/* {{{ Checks whether a given item exists in an array using "dot" notation */ +PHP_FUNCTION(array_has) +{ + HashTable *ht; + zval *key; + zval *result; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_ARRAY_HT(ht) + Z_PARAM_ZVAL(key) + ZEND_PARSE_PARAMETERS_END(); + + /* Handle string keys with dot notation */ + if (Z_TYPE_P(key) == IS_STRING) { + result = array_get_nested(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)); + RETURN_BOOL(result != NULL); + } + /* Handle integer keys (no dot notation support) */ + else if (Z_TYPE_P(key) == IS_LONG) { + RETURN_BOOL(zend_hash_index_exists(ht, Z_LVAL_P(key))); + } + + /* Invalid key type */ + RETURN_FALSE; +} +/* }}} */ + /* {{{ Split array into chunks */ PHP_FUNCTION(array_chunk) { diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 1f3d5617f8df..d3fcfc201c6a 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1903,6 +1903,16 @@ function array_key_exists($key, array $array): bool {} */ function key_exists($key, array $array): bool {} +/** + * @compile-time-eval + */ +function array_get(array $array, string|int|null $key = null, mixed $default = null): mixed {} + +/** + * @compile-time-eval + */ +function array_has(array $array, string|int $key): bool {} + /** * @compile-time-eval */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 991d76d91fc1..621fc020f265 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: 749c71a6220260eb3fb593b982a9d97821e0539b + * Stub hash: 7699cc3f63f513317e5174e0a0c8672ee4b13aa9 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -376,6 +376,17 @@ ZEND_END_ARG_INFO() #define arginfo_key_exists arginfo_array_key_exists +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_get, 0, 1, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, default, IS_MIXED, 0, "null") +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_has, 0, 2, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_LONG, NULL) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) @@ -2406,6 +2417,8 @@ ZEND_FUNCTION(array_any); ZEND_FUNCTION(array_all); ZEND_FUNCTION(array_map); ZEND_FUNCTION(array_key_exists); +ZEND_FUNCTION(array_get); +ZEND_FUNCTION(array_has); ZEND_FUNCTION(array_chunk); ZEND_FUNCTION(array_combine); ZEND_FUNCTION(array_is_list); @@ -3001,6 +3014,8 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(array_map, arginfo_array_map) ZEND_RAW_FENTRY("array_key_exists", zif_array_key_exists, arginfo_array_key_exists, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("key_exists", zif_array_key_exists, arginfo_key_exists, 0, NULL, NULL) + ZEND_RAW_FENTRY("array_get", zif_array_get, arginfo_array_get, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) + ZEND_RAW_FENTRY("array_has", zif_array_has, arginfo_array_has, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_chunk", zif_array_chunk, arginfo_array_chunk, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_combine", zif_array_combine, arginfo_array_combine, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) ZEND_RAW_FENTRY("array_is_list", zif_array_is_list, arginfo_array_is_list, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL) diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index fce41100fc79..eb991dfa9649 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: 749c71a6220260eb3fb593b982a9d97821e0539b */ + * Stub hash: 7699cc3f63f513317e5174e0a0c8672ee4b13aa9 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_749c71a6220260eb3fb593b982a9d97821e0539b_H -#define ZEND_BASIC_FUNCTIONS_DECL_749c71a6220260eb3fb593b982a9d97821e0539b_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_7699cc3f63f513317e5174e0a0c8672ee4b13aa9_H +#define ZEND_BASIC_FUNCTIONS_DECL_7699cc3f63f513317e5174e0a0c8672ee4b13aa9_H typedef enum zend_enum_SortDirection { ZEND_ENUM_SortDirection_Ascending = 1, @@ -20,4 +20,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_749c71a6220260eb3fb593b982a9d97821e0539b_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_7699cc3f63f513317e5174e0a0c8672ee4b13aa9_H */ From e4789d0a52ab999a5bbdf7cfc8fe8189cc0dc614 Mon Sep 17 00:00:00 2001 From: Carlos Granados Date: Fri, 3 Apr 2026 08:30:14 +0200 Subject: [PATCH 2/3] Add tests --- ext/standard/tests/array/array_get.phpt | 63 +++++++++++++++++++++++++ ext/standard/tests/array/array_has.phpt | 60 +++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 ext/standard/tests/array/array_get.phpt create mode 100644 ext/standard/tests/array/array_has.phpt diff --git a/ext/standard/tests/array/array_get.phpt b/ext/standard/tests/array/array_get.phpt new file mode 100644 index 000000000000..038aa2aa7b2c --- /dev/null +++ b/ext/standard/tests/array/array_get.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test array_get() function +--FILE-- + ['desk' => ['price' => 100]]]; + +// Test nested access with dot notation +var_dump(array_get($array, 'products.desk.price')); + +// Test with default value when key doesn't exist +var_dump(array_get($array, 'products.desk.discount', 0)); + +// Test simple key access +$simple = ['name' => 'John', 'age' => 30]; +var_dump(array_get($simple, 'name')); +var_dump(array_get($simple, 'missing', 'default')); + +// Test with integer key +$indexed = ['a', 'b', 'c']; +var_dump(array_get($indexed, 0)); +var_dump(array_get($indexed, 5, 'not found')); + +// Test with null key (returns whole array) +$test = ['foo' => 'bar']; +var_dump(array_get($test, null)); + +// Test nested with missing intermediate key +var_dump(array_get($array, 'products.chair.price', 50)); + +// Test single level key that doesn't exist +var_dump(array_get($array, 'missing')); + +// Test with numeric string in path (like users.0.name) +$users = ['users' => [['name' => 'Alice'], ['name' => 'Bob']]]; +var_dump(array_get($users, 'users.0.name')); +var_dump(array_get($users, 'users.1.age', 70)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_get() *** +int(100) +int(0) +string(4) "John" +string(7) "default" +string(1) "a" +string(9) "not found" +array(1) { + ["foo"]=> + string(3) "bar" +} +int(50) +NULL +string(5) "Alice" +int(70) +Done diff --git a/ext/standard/tests/array/array_has.phpt b/ext/standard/tests/array/array_has.phpt new file mode 100644 index 000000000000..1cbe18933d94 --- /dev/null +++ b/ext/standard/tests/array/array_has.phpt @@ -0,0 +1,60 @@ +--TEST-- +Test array_has() function +--FILE-- + ['name' => 'Desk', 'price' => 100]]; + +// Test nested key exists with dot notation +var_dump(array_has($array, 'product.name')); + +// Test nested key doesn't exist +var_dump(array_has($array, 'product.color')); + +// Test intermediate key doesn't exist +var_dump(array_has($array, 'category.name')); + +// Test simple key access +$simple = ['name' => 'John', 'age' => 30]; +var_dump(array_has($simple, 'name')); +var_dump(array_has($simple, 'missing')); + +// Test with integer key +$indexed = ['a', 'b', 'c']; +var_dump(array_has($indexed, 0)); +var_dump(array_has($indexed, 1)); +var_dump(array_has($indexed, 5)); + +// Test with value that is null (key exists, but value is null) +$withNull = ['key' => null]; +var_dump(array_has($withNull, 'key')); + +// Test with numeric string in path (like users.0.name) +$users = ['users' => [['name' => 'Alice'], ['name' => 'Bob']]]; +var_dump(array_has($users, 'users.0.name')); +var_dump(array_has($users, 'users.1.age')); +var_dump(array_has($users, 'users.2.name')); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_has() *** +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(false) +bool(true) +bool(true) +bool(false) +bool(false) +Done From f3248f207688420b3c89493353fd00e6df84569b Mon Sep 17 00:00:00 2001 From: Carlos Granados Date: Mon, 6 Apr 2026 16:01:48 +0200 Subject: [PATCH 3/3] Accept an array of strings in the $key parameter --- ext/standard/array.c | 138 ++++++++++++++++-------- ext/standard/basic_functions.stub.php | 4 +- ext/standard/basic_functions_arginfo.h | 6 +- ext/standard/basic_functions_decl.h | 8 +- ext/standard/tests/array/array_get.phpt | 14 +++ ext/standard/tests/array/array_has.phpt | 14 +++ 6 files changed, 129 insertions(+), 55 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 66557d5c6744..1626b29fcc27 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6910,48 +6910,69 @@ PHP_FUNCTION(array_key_exists) } /* }}} */ -/* {{{ Helper function to get a nested value from array using dot notation */ -static zval* array_get_nested(HashTable *ht, const char *key, size_t key_len) +/* {{{ Helper function to get a nested value from array using an array of segments */ +static zval* array_get_nested(HashTable *ht, HashTable *segments) { - const char *dot; + zval *segment_val; zval *current; + HashTable *current_ht; + uint32_t idx; + uint32_t num_segments; - /* Find the first dot in the key */ - dot = memchr(key, '.', key_len); + current_ht = ht; + num_segments = zend_hash_num_elements(segments); - if (dot == NULL) { - /* No dot found, this is a simple key lookup */ - zend_string *zkey = zend_string_init(key, key_len, 0); - current = zend_symtable_find(ht, zkey); - zend_string_release(zkey); - return current; - } + /* Iterate through each segment in the array */ + for (idx = 0; idx < num_segments; idx++) { + /* Get the segment at the current index */ + segment_val = zend_hash_index_find(segments, idx); + + if (segment_val == NULL) { + /* Missing segment in array */ + return NULL; + } + + /* Segment must be a string or int */ + if (Z_TYPE_P(segment_val) == IS_STRING) { + current = zend_symtable_find(current_ht, Z_STR_P(segment_val)); + } else if (Z_TYPE_P(segment_val) == IS_LONG) { + current = zend_hash_index_find(current_ht, Z_LVAL_P(segment_val)); + } else { + /* Invalid segment type */ + return NULL; + } + + /* If this is the last segment, return the result */ + if (idx == num_segments - 1) { + return current; + } - /* We have a dot, so we need to recurse */ - size_t segment_len = dot - key; - zend_string *segment = zend_string_init(key, segment_len, 0); - current = zend_symtable_find(ht, segment); - zend_string_release(segment); + /* Check if the segment exists and is an array for next iteration */ + if (current == NULL || Z_TYPE_P(current) != IS_ARRAY) { + return NULL; + } - if (current == NULL || Z_TYPE_P(current) != IS_ARRAY) { - return NULL; + /* Move to the next level */ + current_ht = Z_ARRVAL_P(current); } - /* Recurse into the nested array with the remaining key */ - return array_get_nested(Z_ARRVAL_P(current), dot + 1, key_len - segment_len - 1); + /* Empty segments array */ + return NULL; } /* }}} */ /* {{{ Retrieves a value from a deeply nested array using "dot" notation */ PHP_FUNCTION(array_get) { - HashTable *ht; + zval *array; zval *key = NULL; zval *default_value = NULL; zval *result; + zval segments_array; + HashTable *ht; ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_ARRAY_HT(ht) + Z_PARAM_ARRAY(array) Z_PARAM_ZVAL_OR_NULL(key) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(default_value) @@ -6959,34 +6980,46 @@ PHP_FUNCTION(array_get) /* If key is null, return the whole array */ if (key == NULL || Z_TYPE_P(key) == IS_NULL) { - ZVAL_ARR(return_value, zend_array_dup(ht)); - return; + RETURN_COPY(array); } - /* Handle string keys with dot notation */ - if (Z_TYPE_P(key) == IS_STRING) { - result = array_get_nested(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)); + ht = Z_ARRVAL_P(array); + + /* Handle array keys (array of segments) */ + if (Z_TYPE_P(key) == IS_ARRAY) { + result = array_get_nested(ht, Z_ARRVAL_P(key)); if (result != NULL) { - ZVAL_COPY(return_value, result); - return; + RETURN_COPY(result); } } - /* Handle integer keys (no dot notation support) */ + /* Handle string keys with dot notation - convert to array of segments */ + else if (Z_TYPE_P(key) == IS_STRING) { + /* Use php_explode to split the string by '.' */ + zend_string *delim = ZSTR_CHAR('.'); + array_init(&segments_array); + php_explode(delim, Z_STR_P(key), &segments_array, ZEND_LONG_MAX); + + result = array_get_nested(ht, Z_ARRVAL(segments_array)); + + zval_ptr_dtor(&segments_array); + + if (result != NULL) { + RETURN_COPY(result); + } + } + /* Handle integer keys (simple lookup) */ else if (Z_TYPE_P(key) == IS_LONG) { result = zend_hash_index_find(ht, Z_LVAL_P(key)); if (result != NULL) { - ZVAL_COPY(return_value, result); - return; + RETURN_COPY(result); } } /* Key not found, return default value */ if (default_value != NULL) { - ZVAL_COPY(return_value, default_value); - } else { - RETVAL_NULL(); + RETURN_COPY(default_value); } } /* }}} */ @@ -6994,27 +7027,40 @@ PHP_FUNCTION(array_get) /* {{{ Checks whether a given item exists in an array using "dot" notation */ PHP_FUNCTION(array_has) { - HashTable *ht; + zval *array; zval *key; zval *result; + zval segments_array; + HashTable *ht; ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_ARRAY_HT(ht) + Z_PARAM_ARRAY(array) Z_PARAM_ZVAL(key) ZEND_PARSE_PARAMETERS_END(); - /* Handle string keys with dot notation */ - if (Z_TYPE_P(key) == IS_STRING) { - result = array_get_nested(ht, Z_STRVAL_P(key), Z_STRLEN_P(key)); + ht = Z_ARRVAL_P(array); + + /* Handle array keys (array of segments) */ + if (Z_TYPE_P(key) == IS_ARRAY) { + result = array_get_nested(ht, Z_ARRVAL_P(key)); RETURN_BOOL(result != NULL); } - /* Handle integer keys (no dot notation support) */ - else if (Z_TYPE_P(key) == IS_LONG) { - RETURN_BOOL(zend_hash_index_exists(ht, Z_LVAL_P(key))); + /* Handle string keys with dot notation - convert to array of segments */ + if (Z_TYPE_P(key) == IS_STRING) { + /* Use php_explode to split the string by '.' */ + zend_string *delim = ZSTR_CHAR('.'); + array_init(&segments_array); + php_explode(delim, Z_STR_P(key), &segments_array, ZEND_LONG_MAX); + + result = array_get_nested(ht, Z_ARRVAL(segments_array)); + + zval_ptr_dtor(&segments_array); + RETURN_BOOL(result != NULL); } - /* Invalid key type */ - RETURN_FALSE; + /* Handle integer keys (simple lookup) */ + ZEND_ASSERT(Z_TYPE_P(key) == IS_LONG); + RETURN_BOOL(zend_hash_index_exists(ht, Z_LVAL_P(key))); } /* }}} */ diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index d3fcfc201c6a..dac163777c93 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1906,12 +1906,12 @@ function key_exists($key, array $array): bool {} /** * @compile-time-eval */ -function array_get(array $array, string|int|null $key = null, mixed $default = null): mixed {} +function array_get(array $array, string|int|array|null $key = null, mixed $default = null): mixed {} /** * @compile-time-eval */ -function array_has(array $array, string|int $key): bool {} +function array_has(array $array, string|int|array $key): bool {} /** * @compile-time-eval diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 621fc020f265..37081b47315c 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: 7699cc3f63f513317e5174e0a0c8672ee4b13aa9 + * Stub hash: 2f12dc85580fe1fe947f2de647cfadf6e7696640 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -378,13 +378,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_get, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) - ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_ARRAY|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, default, IS_MIXED, 0, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_has, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) - ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_LONG, NULL) + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_ARRAY, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 0) diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index eb991dfa9649..e67f76aa2a84 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: 7699cc3f63f513317e5174e0a0c8672ee4b13aa9 */ + * Stub hash: 2f12dc85580fe1fe947f2de647cfadf6e7696640 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_7699cc3f63f513317e5174e0a0c8672ee4b13aa9_H -#define ZEND_BASIC_FUNCTIONS_DECL_7699cc3f63f513317e5174e0a0c8672ee4b13aa9_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_2f12dc85580fe1fe947f2de647cfadf6e7696640_H +#define ZEND_BASIC_FUNCTIONS_DECL_2f12dc85580fe1fe947f2de647cfadf6e7696640_H typedef enum zend_enum_SortDirection { ZEND_ENUM_SortDirection_Ascending = 1, @@ -20,4 +20,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_7699cc3f63f513317e5174e0a0c8672ee4b13aa9_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_2f12dc85580fe1fe947f2de647cfadf6e7696640_H */ diff --git a/ext/standard/tests/array/array_get.phpt b/ext/standard/tests/array/array_get.phpt index 038aa2aa7b2c..00678ff0bd02 100644 --- a/ext/standard/tests/array/array_get.phpt +++ b/ext/standard/tests/array/array_get.phpt @@ -42,6 +42,15 @@ $users = ['users' => [['name' => 'Alice'], ['name' => 'Bob']]]; var_dump(array_get($users, 'users.0.name')); var_dump(array_get($users, 'users.1.age', 70)); +// Test with array key (equivalent to dot notation) +var_dump(array_get($array, ['products', 'desk', 'price'])); +var_dump(array_get($simple, ['name'])); +var_dump(array_get($users, ['users', 0, 'name'])); +var_dump(array_get($array, ['products', 'chair', 'price'], 75)); + +// Test with invalid segment type in array key +var_dump(array_get($array, ['products', new stdClass(), 'price'], 'invalid')); + echo "Done"; ?> --EXPECT-- @@ -60,4 +69,9 @@ int(50) NULL string(5) "Alice" int(70) +int(100) +string(4) "John" +string(5) "Alice" +int(75) +string(7) "invalid" Done diff --git a/ext/standard/tests/array/array_has.phpt b/ext/standard/tests/array/array_has.phpt index 1cbe18933d94..14fbe1598b40 100644 --- a/ext/standard/tests/array/array_has.phpt +++ b/ext/standard/tests/array/array_has.phpt @@ -41,6 +41,15 @@ var_dump(array_has($users, 'users.0.name')); var_dump(array_has($users, 'users.1.age')); var_dump(array_has($users, 'users.2.name')); +// Test with array key (equivalent to dot notation) +var_dump(array_has($array, ['product', 'name'])); +var_dump(array_has($simple, ['name'])); +var_dump(array_has($users, ['users', 0, 'name'])); +var_dump(array_has($array, ['product', 'missing'])); + +// Test with invalid segment type in array key +var_dump(array_has($array, ['product', new stdClass()])); + echo "Done"; ?> --EXPECT-- @@ -57,4 +66,9 @@ bool(true) bool(true) bool(false) bool(false) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) Done