Skip to content

Commit a88c7be

Browse files
committed
added use_keys argument to array_filter()
1 parent 9e3bedc commit a88c7be

File tree

3 files changed

+107
-6
lines changed

3 files changed

+107
-6
lines changed

ext/standard/array.c

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4194,17 +4194,19 @@ PHP_FUNCTION(array_filter)
41944194
{
41954195
zval *array;
41964196
zval **operand;
4197-
zval **args[1];
4197+
zval **args[2];
41984198
zval *retval = NULL;
4199+
zval *key = NULL;
41994200
zend_bool have_callback = 0;
4201+
zend_bool use_key = 0;
42004202
char *string_key;
42014203
zend_fcall_info fci = empty_fcall_info;
42024204
zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
42034205
uint string_key_len;
42044206
ulong num_key;
42054207
HashPosition pos;
42064208

4207-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|f", &array, &fci, &fci_cache) == FAILURE) {
4209+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fb", &array, &fci, &fci_cache, &use_key) == FAILURE) {
42084210
return;
42094211
}
42104212

@@ -4217,23 +4219,52 @@ PHP_FUNCTION(array_filter)
42174219
have_callback = 1;
42184220
fci.no_separation = 0;
42194221
fci.retval_ptr_ptr = &retval;
4220-
fci.param_count = 1;
4222+
4223+
if (use_key) {
4224+
fci.param_count = 2;
4225+
args[1] = &key;
4226+
} else {
4227+
fci.param_count = 1;
4228+
}
42214229
}
42224230

42234231
for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
42244232
zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&operand, &pos) == SUCCESS;
42254233
zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)
42264234
) {
4235+
int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos);
4236+
42274237
if (have_callback) {
4238+
if (use_key) {
4239+
MAKE_STD_ZVAL(key);
4240+
/* Set up the key */
4241+
switch (key_type) {
4242+
case HASH_KEY_IS_LONG:
4243+
Z_TYPE_P(key) = IS_LONG;
4244+
Z_LVAL_P(key) = num_key;
4245+
break;
4246+
4247+
case HASH_KEY_IS_STRING:
4248+
ZVAL_STRINGL(key, string_key, string_key_len - 1, 1);
4249+
break;
4250+
}
4251+
}
4252+
42284253
args[0] = operand;
42294254
fci.params = args;
42304255

42314256
if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && retval) {
42324257
if (!zend_is_true(retval)) {
42334258
zval_ptr_dtor(&retval);
4259+
if (use_key) {
4260+
zval_ptr_dtor(&key);
4261+
}
42344262
continue;
42354263
} else {
42364264
zval_ptr_dtor(&retval);
4265+
if (use_key) {
4266+
zval_ptr_dtor(&key);
4267+
}
42374268
}
42384269
} else {
42394270
php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the filter callback");
@@ -4244,7 +4275,7 @@ PHP_FUNCTION(array_filter)
42444275
}
42454276

42464277
zval_add_ref(operand);
4247-
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos)) {
4278+
switch (key_type) {
42484279
case HASH_KEY_IS_STRING:
42494280
zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, operand, sizeof(zval *), NULL);
42504281
break;

ext/standard/tests/array/array_filter_error.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ $extra_arg = 10;
2828

2929
// with one more than the expected number of arguments
3030
echo "-- Testing array_filter() function with more than expected no. of arguments --";
31-
var_dump( array_filter($input, "odd", $extra_arg) );
31+
var_dump( array_filter($input, "odd", $extra_arg, $extra_arg) );
3232

3333
// with incorrect callback function
3434
echo "-- Testing array_filter() function with incorrect callback --";
@@ -42,7 +42,7 @@ echo "Done"
4242
Warning: array_filter() expects at least 1 parameter, 0 given in %s on line %d
4343
NULL
4444
-- Testing array_filter() function with more than expected no. of arguments --
45-
Warning: array_filter() expects at most 2 parameters, 3 given in %s on line %d
45+
Warning: array_filter() expects at most 3 parameters, 4 given in %s on line %d
4646
NULL
4747
-- Testing array_filter() function with incorrect callback --
4848
Warning: array_filter() expects parameter 2 to be a valid callback, function 'even' not found or invalid function name in %s on line %d
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
--TEST--
2+
Test array_filter() function : usage variations - using the array keys inside 'callback'
3+
--FILE--
4+
<?php
5+
/* Prototype : array array_filter(array $input [, callback $callback [, bool $use_keys = false]])
6+
* Description: Filters elements from the array via the callback.
7+
* Source code: ext/standard/array.c
8+
*/
9+
10+
/*
11+
* Using array keys as an argument to the 'callback'
12+
*/
13+
14+
echo "*** Testing array_filter() : usage variations - using array keys in 'callback' ***\n";
15+
16+
$input = array(0, 1, -1, 10, 100, 1000, 'Hello', null);
17+
$small = array(123);
18+
19+
function dump($value, $key)
20+
{
21+
echo "$key = $value\n";
22+
}
23+
24+
var_dump( array_filter($input, 'dump', true) );
25+
26+
echo "*** Testing array_filter() : usage variations - 'callback' filters based on key value ***\n";
27+
28+
function dump2($value, $key)
29+
{
30+
return $key > 4;
31+
}
32+
33+
var_dump( array_filter($input, 'dump2', true) );
34+
35+
echo "*** Testing array_filter() : usage variations - 'callback' expecting second argument ***\n";
36+
37+
var_dump( array_filter($small, 'dump', false) );
38+
39+
echo "Done"
40+
?>
41+
--EXPECTF--
42+
*** Testing array_filter() : usage variations - using array keys in 'callback' ***
43+
0 = 0
44+
1 = 1
45+
2 = -1
46+
3 = 10
47+
4 = 100
48+
5 = 1000
49+
6 = Hello
50+
7 =
51+
array(0) {
52+
}
53+
*** Testing array_filter() : usage variations - 'callback' filters based on key value ***
54+
array(3) {
55+
[5]=>
56+
int(1000)
57+
[6]=>
58+
string(5) "Hello"
59+
[7]=>
60+
NULL
61+
}
62+
*** Testing array_filter() : usage variations - 'callback' expecting second argument ***
63+
64+
Warning: Missing argument 2 for dump() in /home/tjerk/work/php/php-src/ext/standard/tests/array/array_filter_variation10.php on line %d
65+
66+
Notice: Undefined variable: key in /home/tjerk/work/php/php-src/ext/standard/tests/array/array_filter_variation10.php on line %d
67+
= 123
68+
array(0) {
69+
}
70+
Done

0 commit comments

Comments
 (0)