summaryrefslogtreecommitdiff
path: root/ext/standard/array.c
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2003-02-05 17:56:08 +0000
committerIlia Alshanetsky <iliaa@php.net>2003-02-05 17:56:08 +0000
commitf12a6b7663827df15d2879869f9c15c439ad240e (patch)
tree056f9761b42bc80ec87abedfa94990e1820d033f /ext/standard/array.c
parentf660d28143cc105463082eb5e6612c5cc3d114e3 (diff)
downloadphp-git-f12a6b7663827df15d2879869f9c15c439ad240e.tar.gz
Added array_walk_recursive() function that can apply array_walk recursively
to an array.
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r--ext/standard/array.c94
1 files changed, 70 insertions, 24 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index a01459f90d..b97adfab5b 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -943,7 +943,7 @@ PHP_FUNCTION(max)
}
/* }}} */
-static int php_array_walk(HashTable *target_hash, zval **userdata TSRMLS_DC)
+static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive TSRMLS_DC)
{
zval **args[3], /* Arguments to userland function */
*retval_ptr, /* Return value - unused */
@@ -961,33 +961,44 @@ static int php_array_walk(HashTable *target_hash, zval **userdata TSRMLS_DC)
/* Iterate through hash */
while (zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) {
- /* Allocate space for key */
- MAKE_STD_ZVAL(key);
-
- /* Set up the key */
- if (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, &pos) == HASH_KEY_IS_LONG) {
- Z_TYPE_P(key) = IS_LONG;
- Z_LVAL_P(key) = num_key;
- } else {
- ZVAL_STRINGL(key, string_key, string_key_len-1, 1);
- }
-
- /* Call the userland function */
- if (call_user_function_ex(EG(function_table), NULL, *BG(array_walk_func_name),
- &retval_ptr, userdata ? 3 : 2, args, 0, NULL TSRMLS_CC) == SUCCESS) {
-
- zval_ptr_dtor(&retval_ptr);
+ if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) {
+ HashTable *thash;
+
+ thash = HASH_OF(*(args[0]));
+ if (thash == target_hash) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
+ return 0;
+ }
+ php_array_walk(thash, userdata, recursive TSRMLS_CC);
} else {
- char *func_name;
+ /* Allocate space for key */
+ MAKE_STD_ZVAL(key);
- if (zend_is_callable(*BG(array_walk_func_name), 0, &func_name)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", func_name);
+ /* Set up the key */
+ if (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, &pos) == HASH_KEY_IS_LONG) {
+ Z_TYPE_P(key) = IS_LONG;
+ Z_LVAL_P(key) = num_key;
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", func_name);
+ ZVAL_STRINGL(key, string_key, string_key_len-1, 1);
}
+
+ /* Call the userland function */
+ if (call_user_function_ex(EG(function_table), NULL, *BG(array_walk_func_name),
+ &retval_ptr, userdata ? 3 : 2, args, 0, NULL TSRMLS_CC) == SUCCESS) {
+
+ zval_ptr_dtor(&retval_ptr);
+ } else {
+ char *func_name;
- efree(func_name);
- break;
+ if (zend_is_callable(*BG(array_walk_func_name), 0, &func_name)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s()", func_name);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", func_name);
+ }
+
+ efree(func_name);
+ break;
+ }
}
zval_ptr_dtor(&key);
@@ -1026,12 +1037,47 @@ PHP_FUNCTION(array_walk)
BG(array_walk_func_name) = old_walk_func_name;
RETURN_FALSE;
}
- php_array_walk(target_hash, userdata TSRMLS_CC);
+ php_array_walk(target_hash, userdata, 0 TSRMLS_CC);
BG(array_walk_func_name) = old_walk_func_name;
RETURN_TRUE;
}
/* }}} */
+/* {{{ proto bool array_walk_recursive(array input, string funcname [, mixed userdata])
+ Apply a user function recursively to every member of an array */
+PHP_FUNCTION(array_walk_recursive)
+{
+ int argc;
+ zval **array,
+ **userdata = NULL,
+ **old_walk_func_name;
+ HashTable *target_hash;
+
+ argc = ZEND_NUM_ARGS();
+ old_walk_func_name = BG(array_walk_func_name);
+ if (argc < 2 || argc > 3 ||
+ zend_get_parameters_ex(argc, &array, &BG(array_walk_func_name), &userdata) == FAILURE) {
+ BG(array_walk_func_name) = old_walk_func_name;
+ WRONG_PARAM_COUNT;
+ }
+ target_hash = HASH_OF(*array);
+ if (!target_hash) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");
+ BG(array_walk_func_name) = old_walk_func_name;
+ RETURN_FALSE;
+ }
+ if (Z_TYPE_PP(BG(array_walk_func_name)) != IS_ARRAY && Z_TYPE_PP(BG(array_walk_func_name)) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong syntax for function name");
+ BG(array_walk_func_name) = old_walk_func_name;
+ RETURN_FALSE;
+ }
+ php_array_walk(target_hash, userdata, 1 TSRMLS_CC);
+ BG(array_walk_func_name) = old_walk_func_name;
+ RETURN_TRUE;
+}
+/* }}} */
+
+
/* void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
* 0 = return boolean
* 1 = return key