diff --git a/ext/standard/array.c b/ext/standard/array.c index c63caddda8134..2a342d4cb2544 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2377,7 +2377,7 @@ PHP_FUNCTION(array_unshift) Z_ARRVAL_P(stack)->arData = new_hash.arData; Z_ARRVAL_P(stack)->arHash = new_hash.arHash; Z_ARRVAL_P(stack)->pDestructor = new_hash.pDestructor; - + zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack)); /* Clean up and return the number of elements in the stack */ @@ -3650,7 +3650,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int ZVAL_UNDEF(&list->val); if (hash->nNumOfElements > 1) { if (behavior == INTERSECT_NORMAL) { - zend_sort((void *) lists[i], hash->nNumOfElements, + zend_sort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket), intersect_data_compare_func, (swap_func_t)zend_hash_bucket_swap); } else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */ zend_sort((void *) lists[i], hash->nNumOfElements, @@ -4677,8 +4677,7 @@ PHP_FUNCTION(array_product) PHP_FUNCTION(array_reduce) { zval *input; - zval args[2]; - zval *operand; + zval args[3]; zval result; zval retval; zend_fcall_info fci; @@ -4686,6 +4685,10 @@ PHP_FUNCTION(array_reduce) zval *initial = NULL; HashTable *htbl; + zend_ulong arr_num_key; + zend_string *arr_str_key; + zval *arr_val; + if (zend_parse_parameters(ZEND_NUM_ARGS(), "af|z", &input, &fci, &fci_cache, &initial) == FAILURE) { return; } @@ -4707,20 +4710,28 @@ PHP_FUNCTION(array_reduce) } fci.retval = &retval; - fci.param_count = 2; + fci.param_count = 3; fci.no_separation = 0; - ZEND_HASH_FOREACH_VAL(htbl, operand) { + ZEND_HASH_FOREACH_KEY_VAL(htbl, arr_num_key, arr_str_key, arr_val) { ZVAL_COPY(&args[0], &result); - ZVAL_COPY(&args[1], operand); + ZVAL_COPY(&args[1], arr_val); + if (arr_str_key == NULL) { + ZVAL_LONG(&args[2], arr_num_key); + } else { + ZVAL_STRINGL(&args[2], arr_str_key->val, arr_str_key->len); + } + fci.params = args; if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) { + zval_ptr_dtor(&args[2]); zval_ptr_dtor(&args[1]); zval_ptr_dtor(&args[0]); zval_ptr_dtor(&result); ZVAL_COPY_VALUE(&result, &retval); } else { + zval_ptr_dtor(&args[2]); zval_ptr_dtor(&args[1]); zval_ptr_dtor(&args[0]); return; diff --git a/ext/standard/tests/array/array_reduce.phpt b/ext/standard/tests/array/array_reduce.phpt index 94ecca61303a8..fcd39f5514521 100644 --- a/ext/standard/tests/array/array_reduce.phpt +++ b/ext/standard/tests/array/array_reduce.phpt @@ -35,6 +35,16 @@ function reduce_null($w, $v) { return $w . $v; } $initial = null; var_dump(array_reduce($array, 'reduce_null', $initial), $initial); +echo "\n*** Testing array_reduce() to integer with integer array keys ***\n"; +function reduce_integer_keys($w, $v, $k) { return $w * ($k + 1); } +$initial = 1; +var_dump(array_reduce($array, 'reduce_integer_keys', $initial), $initial); + +echo "\n*** Testing array_reduce() to string with string array keys ***\n"; +$stringKeyedArray = ['foo' => 1, 'bar' => 2, 'bas' => 3]; +$initial = 'quux'; +var_dump(array_reduce($stringKeyedArray, function ($w, $v, $k) { return $w . $k; }, $initial), $initial); + echo "\nDone"; ?> --EXPECTF-- @@ -76,4 +86,12 @@ array(4) { string(19) "foofoobarquxquxquux" NULL +*** Testing array_reduce() to integer with integer array keys *** +int(720) +int(1) + +*** Testing array_reduce() to string with string array keys *** +string(13) "quuxfoobarbas" +string(4) "quux" + Done diff --git a/ext/standard/tests/array/array_reduce_variation1.phpt b/ext/standard/tests/array/array_reduce_variation1.phpt index b02a82a7ca3ec..f46af849495af 100644 --- a/ext/standard/tests/array/array_reduce_variation1.phpt +++ b/ext/standard/tests/array/array_reduce_variation1.phpt @@ -1,11 +1,11 @@ --TEST-- -Test array_reduce() function : variation +Test array_reduce() function : variation --FILE-- ===DONE=== --EXPECTF-- *** Testing array_reduce() : variation *** ---- Testing with a callback with too few parameters --- +--- Testing with a callback with one parameter --- int(2) +--- Testing with a callback with two parameters --- +int(3) + --- Testing with a callback with too many parameters --- -Warning: Missing argument 3 for threeArgs() in %sarray_reduce_variation1.php on line %d +Warning: Missing argument 4 for fourArgs() in %sarray_reduce_variation1.php on line %d -Notice: Undefined variable: x in %sarray_reduce_variation1.php on line %d +Notice: Undefined variable: y in %sarray_reduce_variation1.php on line %d int(3) ===DONE=== \ No newline at end of file