diff options
author | Ilia Alshanetsky <iliaa@php.net> | 2003-02-05 17:56:08 +0000 |
---|---|---|
committer | Ilia Alshanetsky <iliaa@php.net> | 2003-02-05 17:56:08 +0000 |
commit | f12a6b7663827df15d2879869f9c15c439ad240e (patch) | |
tree | 056f9761b42bc80ec87abedfa94990e1820d033f /ext/standard/array.c | |
parent | f660d28143cc105463082eb5e6612c5cc3d114e3 (diff) | |
download | php-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.c | 94 |
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 |