Skip to content

Commit c2b7d03

Browse files
More changes after PR review
1 parent 8f494a0 commit c2b7d03

3 files changed

Lines changed: 52 additions & 29 deletions

File tree

ext/standard/array.c

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6917,23 +6917,17 @@ PHP_FUNCTION(array_key_exists)
69176917
static zval* array_get_nested(HashTable *ht, HashTable *path)
69186918
{
69196919
zval *segment_val;
6920-
zval *current;
6921-
HashTable *current_ht;
6922-
uint32_t idx;
6923-
uint32_t num_segments;
6924-
6925-
current_ht = ht;
6926-
num_segments = zend_hash_num_elements(path);
6920+
zval *current = NULL;
6921+
HashTable *current_ht = ht;
6922+
uint32_t num_segments = zend_hash_num_elements(path);
6923+
uint32_t segment_index = 0;
69276924

69286925
/* Iterate through each segment in the path array */
6929-
for (idx = 0; idx < num_segments; idx++) {
6930-
/* Get the segment at the current index */
6931-
segment_val = zend_hash_index_find(path, idx);
6926+
ZEND_HASH_FOREACH_VAL(path, segment_val) {
6927+
segment_index++;
69326928

6933-
if (segment_val == NULL) {
6934-
/* Missing segment in array */
6935-
return NULL;
6936-
}
6929+
/* Dereference segment if it's a reference */
6930+
ZVAL_DEREF(segment_val);
69376931

69386932
/* Segment must be a string or int */
69396933
if (Z_TYPE_P(segment_val) == IS_STRING) {
@@ -6945,22 +6939,27 @@ static zval* array_get_nested(HashTable *ht, HashTable *path)
69456939
return NULL;
69466940
}
69476941

6948-
/* If this is the last segment, return the result */
6949-
if (idx == num_segments - 1) {
6950-
return current;
6942+
/* If segment not found, return NULL */
6943+
if (current == NULL) {
6944+
return NULL;
69516945
}
69526946

6953-
/* Check if the segment exists and is an array for next iteration */
6954-
if (current == NULL || Z_TYPE_P(current) != IS_ARRAY) {
6947+
/* Dereference if it's a reference */
6948+
ZVAL_DEREF(current);
6949+
6950+
/* If current is not an array and we're not at the last segment,
6951+
* we can't continue traversing the path */
6952+
if (Z_TYPE_P(current) != IS_ARRAY && segment_index < num_segments) {
69556953
return NULL;
69566954
}
69576955

6958-
/* Move to the next level */
6959-
current_ht = Z_ARRVAL_P(current);
6960-
}
6956+
/* Update current_ht for next iteration if it's an array */
6957+
if (Z_TYPE_P(current) == IS_ARRAY) {
6958+
current_ht = Z_ARRVAL_P(current);
6959+
}
6960+
} ZEND_HASH_FOREACH_END();
69616961

6962-
/* Empty path array */
6963-
return NULL;
6962+
return current;
69646963
}
69656964
/* }}} */
69666965

@@ -6970,7 +6969,6 @@ PHP_FUNCTION(array_get)
69706969
zval *array;
69716970
zval *path;
69726971
zval *default_value = NULL;
6973-
zval *result;
69746972

69756973
ZEND_PARSE_PARAMETERS_START(2, 3)
69766974
Z_PARAM_ARRAY(array)
@@ -6979,15 +6977,15 @@ PHP_FUNCTION(array_get)
69796977
Z_PARAM_ZVAL(default_value)
69806978
ZEND_PARSE_PARAMETERS_END();
69816979

6982-
result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
6980+
zval *result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
69836981

69846982
if (result != NULL) {
69856983
RETURN_COPY_DEREF(result);
69866984
}
69876985

69886986
/* Path not found, return default value */
69896987
if (default_value != NULL) {
6990-
RETURN_COPY_DEREF(default_value);
6988+
RETURN_COPY(default_value);
69916989
}
69926990
}
69936991
/* }}} */
@@ -6997,14 +6995,13 @@ PHP_FUNCTION(array_has)
69976995
{
69986996
zval *array;
69996997
zval *path;
7000-
zval *result;
70016998

70026999
ZEND_PARSE_PARAMETERS_START(2, 2)
70037000
Z_PARAM_ARRAY(array)
70047001
Z_PARAM_ARRAY(path)
70057002
ZEND_PARSE_PARAMETERS_END();
70067003

7007-
result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
7004+
zval *result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
70087005

70097006
RETURN_BOOL(result != NULL);
70107007
}

ext/standard/tests/array/array_get.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ var_dump($result_with_ref_default);
4848
$default_value = 'changed';
4949
var_dump($result_with_ref_default); // Should still be 'default' (not affected by reference change)
5050

51+
// Test with reference to an array in the path
52+
$array2 = ['world'];
53+
$array_with_ref = ['hello' => &$array2];
54+
var_dump(array_get($array_with_ref, ['hello', 0]));
55+
56+
// Test with path segment that is a reference
57+
$key1 = 'products';
58+
$key2 = 'desk';
59+
$path_with_refs = [&$key1, &$key2, 'price'];
60+
var_dump(array_get($array, $path_with_refs));
61+
5162
echo "Done";
5263
?>
5364
--EXPECT--
@@ -65,4 +76,6 @@ string(8) "original"
6576
string(8) "original"
6677
string(7) "default"
6778
string(7) "default"
79+
string(5) "world"
80+
int(100)
6881
Done

ext/standard/tests/array/array_has.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ var_dump(array_has($withNull, ['key']));
3434
// Test with invalid segment type in array path
3535
var_dump(array_has($array, ['product', new stdClass()]));
3636

37+
// Test with reference to an array in the path
38+
$array2 = ['world'];
39+
$array_with_ref = ['hello' => &$array2];
40+
var_dump(array_has($array_with_ref, ['hello', 0]));
41+
42+
// Test with path segment that is a reference
43+
$key1 = 'product';
44+
$key2 = 'name';
45+
$path_with_refs = [&$key1, &$key2];
46+
var_dump(array_has($array, $path_with_refs));
47+
3748
echo "Done";
3849
?>
3950
--EXPECT--
@@ -48,4 +59,6 @@ bool(true)
4859
bool(false)
4960
bool(true)
5061
bool(false)
62+
bool(true)
63+
bool(true)
5164
Done

0 commit comments

Comments
 (0)