summaryrefslogtreecommitdiff
path: root/ext/standard
diff options
context:
space:
mode:
authordatibbaw <datibbaw@php.net>2013-09-26 11:10:24 +0800
committerTjerk Meesters <datibbaw@php.net>2013-09-28 00:06:04 +0800
commit0492145e58bda8fed9f64992a9b8d054d9c80758 (patch)
treeb67e505dd24cc5ebd8d2eb8d55de2094bd8fee5f /ext/standard
parentb8653d34579409131b8dc6d92e7ac30e28fa95a6 (diff)
downloadphp-git-0492145e58bda8fed9f64992a9b8d054d9c80758.tar.gz
added bitmask variation
Diffstat (limited to 'ext/standard')
-rw-r--r--ext/standard/array.c36
-rw-r--r--ext/standard/php_array.h4
-rw-r--r--ext/standard/tests/array/array_filter_variation10.phpt35
3 files changed, 59 insertions, 16 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 1f98ef16f2..13148ec6f0 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -127,6 +127,10 @@ PHP_MINIT_FUNCTION(array) /* {{{ */
REGISTER_LONG_CONSTANT("COUNT_NORMAL", COUNT_NORMAL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("COUNT_RECURSIVE", COUNT_RECURSIVE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_BOTH", ARRAY_FILTER_USE_BOTH, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_KEY", ARRAY_FILTER_USE_KEY, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("ARRAY_FILTER_USE_VALUE", ARRAY_FILTER_USE_VALUE, CONST_CS | CONST_PERSISTENT);
+
return SUCCESS;
}
/* }}} */
@@ -4198,7 +4202,7 @@ PHP_FUNCTION(array_filter)
zval *retval = NULL;
zval *key = NULL;
zend_bool have_callback = 0;
- zend_bool use_key = 0;
+ long use_type = ARRAY_FILTER_USE_VALUE;
char *string_key;
zend_fcall_info fci = empty_fcall_info;
zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
@@ -4206,7 +4210,7 @@ PHP_FUNCTION(array_filter)
ulong num_key;
HashPosition pos;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fb", &array, &fci, &fci_cache, &use_key) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fl", &array, &fci, &fci_cache, &use_type) == FAILURE) {
return;
}
@@ -4220,11 +4224,14 @@ PHP_FUNCTION(array_filter)
fci.no_separation = 0;
fci.retval_ptr_ptr = &retval;
- if (use_key) {
+ if (use_type == ARRAY_FILTER_USE_BOTH) {
fci.param_count = 2;
args[1] = &key;
} else {
fci.param_count = 1;
+ if (use_type == ARRAY_FILTER_USE_KEY) {
+ args[0] = &key;
+ }
}
}
@@ -4235,7 +4242,7 @@ PHP_FUNCTION(array_filter)
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) {
+ if (use_type != ARRAY_FILTER_USE_VALUE) {
MAKE_STD_ZVAL(key);
/* Set up the key */
switch (key_type) {
@@ -4250,21 +4257,20 @@ PHP_FUNCTION(array_filter)
}
}
- args[0] = operand;
+ if (use_type != ARRAY_FILTER_USE_KEY) {
+ 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);
- }
+ int retval_true = zend_is_true(retval);
+
+ zval_ptr_dtor(&retval);
+ if (use_type != ARRAY_FILTER_USE_VALUE) {
+ zval_ptr_dtor(&key);
+ }
+ if (!retval_true) {
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");
diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h
index 1cf2779071..7d9733d296 100644
--- a/ext/standard/php_array.h
+++ b/ext/standard/php_array.h
@@ -117,6 +117,10 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC);
#define PHP_SORT_NATURAL 6
#define PHP_SORT_FLAG_CASE 8
+#define ARRAY_FILTER_USE_BOTH 1
+#define ARRAY_FILTER_USE_KEY 2
+#define ARRAY_FILTER_USE_VALUE 3
+
ZEND_BEGIN_MODULE_GLOBALS(array)
int *multisort_flags[2];
int (*compare_func)(zval *result, zval *op1, zval *op2 TSRMLS_DC);
diff --git a/ext/standard/tests/array/array_filter_variation10.phpt b/ext/standard/tests/array/array_filter_variation10.phpt
index 1eec4591a1..25698c55c2 100644
--- a/ext/standard/tests/array/array_filter_variation10.phpt
+++ b/ext/standard/tests/array/array_filter_variation10.phpt
@@ -2,7 +2,7 @@
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]])
+/* Prototype : array array_filter(array $input [, callback $callback [, bool $use_type = ARRAY_FILTER_USE_VALUE]])
* Description: Filters elements from the array via the callback.
* Source code: ext/standard/array.c
*/
@@ -36,6 +36,16 @@ echo "*** Testing array_filter() : usage variations - 'callback' expecting secon
var_dump( array_filter($small, 'dump', false) );
+echo "*** Testing array_filter() with various use types ***\n";
+
+$mixed = array(1 => 'a', 2 => 'b', 'a' => 1, 'b' => 2);
+
+var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_KEY));
+
+var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_VALUE));
+
+var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_BOTH));
+
echo "Done"
?>
--EXPECTF--
@@ -67,4 +77,27 @@ Notice: Undefined variable: key in %s on line %d
= 123
array(0) {
}
+*** Testing array_filter() with various use types ***
+array(2) {
+ [1]=>
+ string(1) "a"
+ [2]=>
+ string(1) "b"
+}
+array(2) {
+ ["a"]=>
+ int(1)
+ ["b"]=>
+ int(2)
+}
+
+Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44
+
+Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44
+
+Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44
+
+Warning: is_numeric() expects exactly 1 parameter, 2 given in %s on line 44
+array(0) {
+}
Done