diff options
author | datibbaw <datibbaw@php.net> | 2013-02-21 14:42:28 +0800 |
---|---|---|
committer | Tjerk Meesters <datibbaw@php.net> | 2013-09-28 00:06:03 +0800 |
commit | a88c7be88b57162eb0a89ff1b7c2ef60ac1de935 (patch) | |
tree | b8541cdc2a828d544181335fd3f712a935331668 /ext/standard | |
parent | 9e3bedcd73265acb3d190c894860bd9aa1015121 (diff) | |
download | php-git-a88c7be88b57162eb0a89ff1b7c2ef60ac1de935.tar.gz |
added use_keys argument to array_filter()
Diffstat (limited to 'ext/standard')
-rw-r--r-- | ext/standard/array.c | 39 | ||||
-rw-r--r-- | ext/standard/tests/array/array_filter_error.phpt | 4 | ||||
-rw-r--r-- | ext/standard/tests/array/array_filter_variation10.phpt | 70 |
3 files changed, 107 insertions, 6 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c index ae6e5d266f..1f98ef16f2 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4194,9 +4194,11 @@ PHP_FUNCTION(array_filter) { zval *array; zval **operand; - zval **args[1]; + zval **args[2]; zval *retval = NULL; + zval *key = NULL; zend_bool have_callback = 0; + zend_bool use_key = 0; char *string_key; zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; @@ -4204,7 +4206,7 @@ PHP_FUNCTION(array_filter) ulong num_key; HashPosition pos; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|f", &array, &fci, &fci_cache) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fb", &array, &fci, &fci_cache, &use_key) == FAILURE) { return; } @@ -4217,23 +4219,52 @@ PHP_FUNCTION(array_filter) have_callback = 1; fci.no_separation = 0; fci.retval_ptr_ptr = &retval; - fci.param_count = 1; + + if (use_key) { + fci.param_count = 2; + args[1] = &key; + } else { + fci.param_count = 1; + } } for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&operand, &pos) == SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) ) { + int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos); + if (have_callback) { + if (use_key) { + MAKE_STD_ZVAL(key); + /* Set up the key */ + switch (key_type) { + case HASH_KEY_IS_LONG: + Z_TYPE_P(key) = IS_LONG; + Z_LVAL_P(key) = num_key; + break; + + case HASH_KEY_IS_STRING: + ZVAL_STRINGL(key, string_key, string_key_len - 1, 1); + break; + } + } + args[0] = operand; fci.params = args; if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && retval) { if (!zend_is_true(retval)) { zval_ptr_dtor(&retval); + if (use_key) { + zval_ptr_dtor(&key); + } continue; } else { zval_ptr_dtor(&retval); + if (use_key) { + zval_ptr_dtor(&key); + } } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the filter callback"); @@ -4244,7 +4275,7 @@ PHP_FUNCTION(array_filter) } zval_add_ref(operand); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos)) { + switch (key_type) { case HASH_KEY_IS_STRING: zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, operand, sizeof(zval *), NULL); break; diff --git a/ext/standard/tests/array/array_filter_error.phpt b/ext/standard/tests/array/array_filter_error.phpt index 20e89aa4b7..3f8f51bc14 100644 --- a/ext/standard/tests/array/array_filter_error.phpt +++ b/ext/standard/tests/array/array_filter_error.phpt @@ -28,7 +28,7 @@ $extra_arg = 10; // with one more than the expected number of arguments echo "-- Testing array_filter() function with more than expected no. of arguments --"; -var_dump( array_filter($input, "odd", $extra_arg) ); +var_dump( array_filter($input, "odd", $extra_arg, $extra_arg) ); // with incorrect callback function echo "-- Testing array_filter() function with incorrect callback --"; @@ -42,7 +42,7 @@ echo "Done" Warning: array_filter() expects at least 1 parameter, 0 given in %s on line %d NULL -- Testing array_filter() function with more than expected no. of arguments -- -Warning: array_filter() expects at most 2 parameters, 3 given in %s on line %d +Warning: array_filter() expects at most 3 parameters, 4 given in %s on line %d NULL -- Testing array_filter() function with incorrect callback -- Warning: array_filter() expects parameter 2 to be a valid callback, function 'even' not found or invalid function name in %s on line %d diff --git a/ext/standard/tests/array/array_filter_variation10.phpt b/ext/standard/tests/array/array_filter_variation10.phpt new file mode 100644 index 0000000000..9a5b2a4a30 --- /dev/null +++ b/ext/standard/tests/array/array_filter_variation10.phpt @@ -0,0 +1,70 @@ +--TEST-- +Test array_filter() function : usage variations - using the array keys inside 'callback' +--FILE-- +<?php +/* Prototype : array array_filter(array $input [, callback $callback [, bool $use_keys = false]]) + * Description: Filters elements from the array via the callback. + * Source code: ext/standard/array.c +*/ + +/* +* Using array keys as an argument to the 'callback' +*/ + +echo "*** Testing array_filter() : usage variations - using array keys in 'callback' ***\n"; + +$input = array(0, 1, -1, 10, 100, 1000, 'Hello', null); +$small = array(123); + +function dump($value, $key) +{ + echo "$key = $value\n"; +} + +var_dump( array_filter($input, 'dump', true) ); + +echo "*** Testing array_filter() : usage variations - 'callback' filters based on key value ***\n"; + +function dump2($value, $key) +{ + return $key > 4; +} + +var_dump( array_filter($input, 'dump2', true) ); + +echo "*** Testing array_filter() : usage variations - 'callback' expecting second argument ***\n"; + +var_dump( array_filter($small, 'dump', false) ); + +echo "Done" +?> +--EXPECTF-- +*** Testing array_filter() : usage variations - using array keys in 'callback' *** +0 = 0 +1 = 1 +2 = -1 +3 = 10 +4 = 100 +5 = 1000 +6 = Hello +7 = +array(0) { +} +*** Testing array_filter() : usage variations - 'callback' filters based on key value *** +array(3) { + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL +} +*** Testing array_filter() : usage variations - 'callback' expecting second argument *** + +Warning: Missing argument 2 for dump() in /home/tjerk/work/php/php-src/ext/standard/tests/array/array_filter_variation10.php on line %d + +Notice: Undefined variable: key in /home/tjerk/work/php/php-src/ext/standard/tests/array/array_filter_variation10.php on line %d + = 123 +array(0) { +} +Done |