Skip to content

Commit 6f1bc06

Browse files
More changes after PR review
1 parent 4af39b9 commit 6f1bc06

File tree

3 files changed

+52
-29
lines changed

3 files changed

+52
-29
lines changed

ext/standard/array.c

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

69306927
/* Iterate through each segment in the path array */
6931-
for (idx = 0; idx < num_segments; idx++) {
6932-
/* Get the segment at the current index */
6933-
segment_val = zend_hash_index_find(path, idx);
6928+
ZEND_HASH_FOREACH_VAL(path, segment_val) {
6929+
segment_index++;
69346930

6935-
if (segment_val == NULL) {
6936-
/* Missing segment in array */
6937-
return NULL;
6938-
}
6931+
/* Dereference segment if it's a reference */
6932+
ZVAL_DEREF(segment_val);
69396933

69406934
/* Segment must be a string or int */
69416935
if (Z_TYPE_P(segment_val) == IS_STRING) {
@@ -6947,22 +6941,27 @@ static zval* array_get_nested(HashTable *ht, HashTable *path)
69476941
return NULL;
69486942
}
69496943

6950-
/* If this is the last segment, return the result */
6951-
if (idx == num_segments - 1) {
6952-
return current;
6944+
/* If segment not found, return NULL */
6945+
if (current == NULL) {
6946+
return NULL;
69536947
}
69546948

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

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

6964-
/* Empty path array */
6965-
return NULL;
6964+
return current;
69666965
}
69676966
/* }}} */
69686967

@@ -6972,7 +6971,6 @@ PHP_FUNCTION(array_get)
69726971
zval *array;
69736972
zval *path;
69746973
zval *default_value = NULL;
6975-
zval *result;
69766974

69776975
ZEND_PARSE_PARAMETERS_START(2, 3)
69786976
Z_PARAM_ARRAY(array)
@@ -6981,15 +6979,15 @@ PHP_FUNCTION(array_get)
69816979
Z_PARAM_ZVAL(default_value)
69826980
ZEND_PARSE_PARAMETERS_END();
69836981

6984-
result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
6982+
zval *result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
69856983

69866984
if (result != NULL) {
69876985
RETURN_COPY_DEREF(result);
69886986
}
69896987

69906988
/* Path not found, return default value */
69916989
if (default_value != NULL) {
6992-
RETURN_COPY_DEREF(default_value);
6990+
RETURN_COPY(default_value);
69936991
}
69946992
}
69956993
/* }}} */
@@ -6999,14 +6997,13 @@ PHP_FUNCTION(array_has)
69996997
{
70006998
zval *array;
70016999
zval *path;
7002-
zval *result;
70037000

70047001
ZEND_PARSE_PARAMETERS_START(2, 2)
70057002
Z_PARAM_ARRAY(array)
70067003
Z_PARAM_ARRAY(path)
70077004
ZEND_PARSE_PARAMETERS_END();
70087005

7009-
result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
7006+
zval *result = array_get_nested(Z_ARRVAL_P(array), Z_ARRVAL_P(path));
70107007

70117008
RETURN_BOOL(result != NULL);
70127009
}

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)