Edit report at http://bugs.php.net/bug.php?id=6911&edit=1
ID: 6911 Updated by: johan...@php.net Reported by: john at elysium dot ltd dot uk Summary: Problem with array_merge(_recursive) -Status: Open +Status: Bogus Type: Feature/Change Request -Package: Feature/Change Request +Package: *General Issues Operating System: RH 6.2 PHP Version: 4.0.2 Block user comment: N New Comment: array_combine meanwhile exists Previous Comments: ------------------------------------------------------------------------ [2000-09-27 21:25:13] john at elysium dot ltd dot uk I had a problem with array_merge_recursive, in that I wanted any replicated content (by key) in the source array, to replace (and not be added to) the destination array. I wanted this as I was updating HTTP_SESSION_VARS with HTTP_POST_VARS e.g. Using array_merge_recursive: $source = array("new_value", "string_key" => array("bob", "billy", "fred")); $destination = array("value", "string_key" => array("bob", "frank", "fred"), "another_value"); Resulting array will be: array("value", "string_key" => array("bob", "frank", "fred", "bob", "billy", "fred"), "another_value", "new_value"); I required the output to be: array("new_value", "string_key" => array("bob", "billy", "fred"), "another_value"); Rgds John Legg diff -cPr php-4.0.2.orig/ext/standard/array.c php-4.0.2/ext/standard/array.c *** php-4.0.2.orig/ext/standard/array.c Tue Aug 22 19:39:29 2000 --- php-4.0.2/ext/standard/array.c Wed Sep 27 15:00:00 2000 *************** *** 1832,1837 **** --- 1832,1919 ---- } /* }}} */ + static void php_array_combine_impl(HashTable *dest, HashTable *src, int recursive) + { + zval **src_entry, **dest_entry; + char *string_key; + ulong num_key; + + zend_hash_internal_pointer_reset(src); + while(zend_hash_get_current_data(src, (void **)&src_entry) == SUCCESS) { + switch (zend_hash_get_current_key(src, &string_key, &num_key)) { + case HASH_KEY_IS_STRING: + if (recursive && (*src_entry)->type == IS_ARRAY && + zend_hash_find(dest, string_key, strlen(string_key) + 1, + (void **)&dest_entry) == SUCCESS) { + php_array_combine_impl(Z_ARRVAL_PP(dest_entry), + Z_ARRVAL_PP(src_entry), recursive); + } else { + (*src_entry)->refcount++; + zend_hash_update(dest, string_key, strlen(string_key)+1, + src_entry, sizeof(zval *), NULL); + } + efree(string_key); + break; + + case HASH_KEY_IS_LONG: + (*src_entry)->refcount++; + if (zend_hash_index_exists(dest, num_key)) { + zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL); + } else { + zend_hash_next_index_insert(dest, src_entry, sizeof(zval *), NULL); + } + break; + } + zend_hash_move_forward(src); + } + } + + static void php_array_combine(INTERNAL_FUNCTION_PARAMETERS, int recursive) + { + zval ***args = NULL; + int argc, + i; + + /* Get the argument count and check it */ + argc = ZEND_NUM_ARGS(); + if (argc < 2) { + WRONG_PARAM_COUNT; + } + + /* Allocate arguments array and get the arguments, checking for errors. */ + args = (zval ***)emalloc(argc * sizeof(zval **)); + if (zend_get_parameters_array_ex(argc, args) == FAILURE) { + efree(args); + WRONG_PARAM_COUNT; + } + + array_init(return_value); + + for (i=0; i<argc; i++) { + convert_to_array_ex(args[i]); + php_array_combine_impl(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive); + } + + efree(args); + } + + /* {{{ proto array array_combine(array arr1, array arr2 [, mixed ...]) + Combines elements from passed arrays into one array, key value pairs + in arr2 take precedence over key value pairs in arr1 */ + PHP_FUNCTION(array_combine) + { + php_array_combine(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); + } + /* }}} */ + + /* {{{ proto array array_combine_recursive(array arr1, array arr2 [, mixed ...]) + Recursively Combines elements from passed arrays into one array, key value pairs + in arr2 take precedence over key value pairs in arr1 */ + PHP_FUNCTION(array_combine_recursive) + { + php_array_combine(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); + } + /* }}} */ /* {{{ proto array array_keys(array input [, mixed search_value]) Return just the keys from the input array, optionally only for the specified search_value */ diff -cPr php-4.0.2.orig/ext/standard/basic_functions.c php-4.0.2/ext/standard/basic_functions.c *** php-4.0.2.orig/ext/standard/basic_functions.c Sun Aug 27 23:46:40 2000 --- php-4.0.2/ext/standard/basic_functions.c Wed Sep 27 15:01:15 2000 *************** *** 520,525 **** --- 520,527 ---- PHP_FE(array_slice, NULL) PHP_FE(array_merge, NULL) PHP_FE(array_merge_recursive, NULL) + PHP_FE(array_combine, NULL) + PHP_FE(array_combine_recursive, NULL) PHP_FE(array_keys, NULL) PHP_FE(array_values, NULL) PHP_FE(array_count_values, NULL) diff -cPr php-4.0.2.orig/ext/standard/php_array.h php-4.0.2/ext/standard/php_array.h *** php-4.0.2.orig/ext/standard/php_array.h Mon Jul 24 02:39:49 2000 --- php-4.0.2/ext/standard/php_array.h Wed Sep 27 15:00:52 2000 *************** *** 62,67 **** --- 62,69 ---- PHP_FUNCTION(array_slice); PHP_FUNCTION(array_merge); PHP_FUNCTION(array_merge_recursive); + PHP_FUNCTION(array_combine); + PHP_FUNCTION(array_combine_recursive); PHP_FUNCTION(array_keys); PHP_FUNCTION(array_values); PHP_FUNCTION(array_count_values); ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=6911&edit=1