Skip to content

Array_get and array_has functions#21637

Open
carlos-granados wants to merge 2 commits intophp:masterfrom
carlos-granados:array-get-array-has
Open

Array_get and array_has functions#21637
carlos-granados wants to merge 2 commits intophp:masterfrom
carlos-granados:array-get-array-has

Conversation

@carlos-granados
Copy link
Copy Markdown

This PR proposes adding two small, focused array functions to ext/standard for retrieving and checking nested array elements using dot notation, in a single step.

See the related RFC:
https://wiki.php.net/rfc/array_get_and_array_has


if (dot == NULL) {
/* No dot found, this is a simple key lookup */
zend_string *zkey = zend_string_init(key, key_len, 0);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have a zend_string already here, then you can avoid the allocation.
In general, use zend_symtable_str_find (also below).


/* 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));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid a duplication, just return a copy with the refcount. Sadly, ZVAL_ARR sucks as it doesn't take into account the mutability in the type info; so you'd have to use Z_PARAM_ARRAY so you have a zval that you can use RETURN_COPY on.

result = array_get_nested(ht, Z_STRVAL_P(key), Z_STRLEN_P(key));

if (result != NULL) {
ZVAL_COPY(return_value, result);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RETURN_COPY

result = zend_hash_index_find(ht, Z_LVAL_P(key));

if (result != NULL) {
ZVAL_COPY(return_value, result);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RETURN_COPY


/* Key not found, return default value */
if (default_value != NULL) {
ZVAL_COPY(return_value, default_value);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RETURN_COPY

if (default_value != NULL) {
ZVAL_COPY(return_value, default_value);
} else {
RETVAL_NULL();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessary, the return value is NULL implicitly

}

/* Invalid key type */
RETURN_FALSE;
Copy link
Copy Markdown
Member

@ndossche ndossche Apr 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is impossible by using the type int|string, use ZEND_UNREACHABLE();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet impossible, because Z_PARAM_ZVAL, but yes, it should be properly typed in ZPP.

}

/* Recurse into the nested array with the remaining key */
return array_get_nested(Z_ARRVAL_P(current), dot + 1, key_len - segment_len - 1);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless this gets tailcall eliminated, you have primitive recursion here which can overflow. Best to write an explicit loop.

current = zend_symtable_find(ht, segment);
zend_string_release(segment);

if (current == NULL || Z_TYPE_P(current) != IS_ARRAY) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this handle references properly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants