]> granicus.if.org Git - php/commitdiff
@- Added array_merge_recursive() that will recursively merge values
authorAndrei Zmievski <andrei@php.net>
Tue, 30 May 2000 17:03:56 +0000 (17:03 +0000)
committerAndrei Zmievski <andrei@php.net>
Tue, 30 May 2000 17:03:56 +0000 (17:03 +0000)
@  under the same keys. (Andrei)

ext/standard/array.c
ext/standard/basic_functions.c
ext/standard/php_array.h

index 82b282f1c15bc8924b4d6650ed91be754e02c6c8..fa1c210f8329ad56b38075c764b087b3a56812a4 100644 (file)
@@ -1734,17 +1734,48 @@ PHP_FUNCTION(array_slice)
 /* }}} */
 
 
-/* {{{ proto array array_merge(array arr1, array arr2 [, ...])
-   Merges elements from passed arrays into one array */
-PHP_FUNCTION(array_merge)
+static void php_array_merge_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 &&
+                                       zend_hash_find(dest, string_key, strlen(string_key) + 1,
+                                                                  (void **)&dest_entry) == SUCCESS) {
+                                       convert_to_array_ex(dest_entry);
+                                       convert_to_array_ex(src_entry);
+                                       php_array_merge_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++;
+                               zend_hash_next_index_insert(dest, src_entry, sizeof(zval *), NULL);
+                               break;
+               }
+
+               zend_hash_move_forward(src);
+       }
+}
+
+static void php_array_merge(INTERNAL_FUNCTION_PARAMETERS, int recursive)
 {
-       zval      ***args = NULL,
-                          **entry;
-       HashTable       *hash;
+       zval      ***args = NULL;
        int                      argc,
                                 i;
-       char            *string_key;
-       ulong            num_key;
 
        /* Get the argument count and check it */       
        argc = ARG_COUNT(ht);
@@ -1762,35 +1793,29 @@ PHP_FUNCTION(array_merge)
        array_init(return_value);
        
        for (i=0; i<argc; i++) {
-               if ((*args[i])->type != IS_ARRAY) {
-                       php_error(E_WARNING, "Skipping argument #%d to array_merge(), since it's not an array", i+1);
-                       continue;
-               }
-               hash = (*args[i])->value.ht;
-               
-               zend_hash_internal_pointer_reset(hash);
-               while(zend_hash_get_current_data(hash, (void **)&entry) == SUCCESS) {
-                       (*entry)->refcount++;
-                       
-                       switch (zend_hash_get_current_key(hash, &string_key, &num_key)) {
-                               case HASH_KEY_IS_STRING:
-                                       zend_hash_update(return_value->value.ht, string_key, strlen(string_key)+1,
-                                                                        entry, sizeof(zval *), NULL);
-                                       efree(string_key);
-                                       break;
-
-                               case HASH_KEY_IS_LONG:
-                                       zend_hash_next_index_insert(return_value->value.ht,
-                                                                                               entry, sizeof(zval *), NULL);
-                                       break;
-                       }
-
-                       zend_hash_move_forward(hash);
-               }
+               convert_to_array_ex(args[i]);
+               php_array_merge_impl(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive);
        }
        
        efree(args);
 }
+
+
+/* {{{ proto array array_merge(array arr1, array arr2 [, ...])
+   Merges elements from passed arrays into one array */
+PHP_FUNCTION(array_merge)
+{
+       php_array_merge(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+
+/* {{{ proto array array_merge(array arr1, array arr2 [, ...])
+   Recursively merges elements from passed arrays into one array */
+PHP_FUNCTION(array_merge_recursive)
+{
+       php_array_merge(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
 /* }}} */
 
 
index f233efe6cb35e13f604f9ec1fd37aa46c51a111a..a1f2ac8149eaa502e2996805a143914a9d297821 100644 (file)
@@ -495,6 +495,7 @@ function_entry basic_functions[] = {
        PHP_FE(array_splice,                                                    first_arg_force_ref)
        PHP_FE(array_slice,                                                             NULL)
        PHP_FE(array_merge,                                                             NULL)
+       PHP_FE(array_merge_recursive,                                   NULL)
        PHP_FE(array_keys,                                                              NULL)
        PHP_FE(array_values,                                                    NULL)
        PHP_FE(array_count_values,                                              NULL)
index d6f073bab6309cc951cd12b7b2b627f83f8c132f..38b3174c24c52a84cc632ce696b861152e72b0aa 100644 (file)
@@ -61,6 +61,7 @@ PHP_FUNCTION(array_unshift);
 PHP_FUNCTION(array_splice);
 PHP_FUNCTION(array_slice);
 PHP_FUNCTION(array_merge);
+PHP_FUNCTION(array_merge_recursive);
 PHP_FUNCTION(array_keys);
 PHP_FUNCTION(array_values);
 PHP_FUNCTION(array_count_values);