Array_get and array_has functions#21637
Conversation
|
|
||
| if (dot == NULL) { | ||
| /* No dot found, this is a simple key lookup */ | ||
| zend_string *zkey = zend_string_init(key, key_len, 0); |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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); |
| result = zend_hash_index_find(ht, Z_LVAL_P(key)); | ||
|
|
||
| if (result != NULL) { | ||
| ZVAL_COPY(return_value, result); |
|
|
||
| /* Key not found, return default value */ | ||
| if (default_value != NULL) { | ||
| ZVAL_COPY(return_value, default_value); |
| if (default_value != NULL) { | ||
| ZVAL_COPY(return_value, default_value); | ||
| } else { | ||
| RETVAL_NULL(); |
There was a problem hiding this comment.
Not necessary, the return value is NULL implicitly
| } | ||
|
|
||
| /* Invalid key type */ | ||
| RETURN_FALSE; |
There was a problem hiding this comment.
This case is impossible by using the type int|string, use ZEND_UNREACHABLE();
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
Does this handle references properly?
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