downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

array_merge> <array_map
Last updated: Fri, 06 Nov 2009

view this page in

array_merge_recursive

(PHP 4 >= 4.0.1, PHP 5)

array_merge_recursiveFunde dois ou mais arrays recursivamente

Descrição

array array_merge_recursive ( array $array1 [, array $... ] )

array_merge_recursive() funde os elementos de um ou mais arrays de forma que os elementos de um são colocados no final do array anterior. Retorna o array resultante da fusão.

Se os arrays dados tem as mesmas chaves string, então os valores para uma chave são fundidos em um array, e isso é feito recursivamente, sendo que, se um dos valores for um array também, este função irá fundi-lo com os valores correspondentes no array resultante também. Se, no entanto, os arrays tem as mesmas chaves numéricas, o último valor para uma chave não sobrescreverá o valor original, e sim adicionado ao array resultante.

Parâmetros

array1

Array inicial para fundir.

array

Lista variável de arrays para fundir recursivamente.

Valor Retornado

Um array de valores resultados da fusão dos argumentos.

Exemplos

Exemplo #1 Exemplo de array_merge_recursive()

<?php
$ar1 
= array("cor" => array ("favorita" => "vermelho"), 5);
$ar2 = array(10"cor" => array ("favorita" => "verde""azul"));
$result array_merge_recursive($ar1$ar2);
?>

O exemplo acima irá imprimir:

Array
(
    [cor] => Array
        (
            [favorita] => Array
                (
                    [0] => vermelho
                    [1] => verde
                )

            [0] => azul
        )

    [0] => 5
    [1] => 10
)

Veja Também



array_merge> <array_map
Last updated: Fri, 06 Nov 2009
 
add a note add a note User Contributed Notes
array_merge_recursive
drvali at hotmail dot com
06-Oct-2009 04:31
<?php
/**
 * Merges any number of arrays of any dimensions, the later overwriting
 * previous keys, unless the key is numeric, in whitch case, duplicated
 * values will not be added.
 *
 * The arrays to be merged are passed as arguments to the function.
 *
 * @access public
 * @return array Resulting array, once all have been merged
 */
function array_merge_replace_recursive() {
   
// Holds all the arrays passed
   
$params = & func_get_args ();
   
   
// First array is used as the base, everything else overwrites on it
   
$return = array_shift ( $params );
   
   
// Merge all arrays on the first array
   
foreach ( $params as $array ) {
        foreach (
$array as $key => $value ) {
           
// Numeric keyed values are added (unless already there)
           
if (is_numeric ( $key ) && (! in_array ( $value, $return ))) {
                if (
is_array ( $value )) {
                   
$return [] = $this->array_merge_replace_recursive ( $return [$$key], $value );
                } else {
                   
$return [] = $value;
                }
               
           
// String keyed values are replaced
           
} else {
                if (isset (
$return [$key] ) && is_array ( $value ) && is_array ( $return [$key] )) {
                   
$return [$key] = $this->array_merge_replace_recursive ( $return [$$key], $value );
                } else {
                   
$return [$key] = $value;
                }
            }
        }
    }
   
    return
$return;
}

$a = array (
   
"a" => 1,
   
"b" => 2,
   
'foo',
   
'bar'
);
$b = array (
   
"a" => 2,
   
"c" => 3,
   
'foo'
);

$c = array_merge_replace_recursive ( $a, $b );
print_r ( $a );
print_r ( $b );
print_r ( $c );
?>

Output:
Array
(
    [a] => 1
    [b] => 2
    [0] => foo
    [1] => bar
)
Array
(
    [a] => 2
    [c] => 3
    [0] => foo
)
Array
(
    [a] => 2
    [b] => 2
    [0] => foo
    [1] => bar
    [c] => 3
)
gabriel dot sobrinho at gmail dot com
14-Jul-2009 02:56
I refactored the Daniel's function and I got it:

<?php
/**
 * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
 * keys to arrays rather than overwriting the value in the first array with the duplicate
 * value in the second array, as array_merge does. I.e., with array_merge_recursive,
 * this happens (documented behavior):
 *
 * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('org value', 'new value'));
 *
 * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
 * Matching keys' values in the second array overwrite those in the first array, as is the
 * case with array_merge, i.e.:
 *
 * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('new value'));
 *
 * Parameters are passed by reference, though only for performance reasons. They're not
 * altered by this function.
 *
 * @param array $array1
 * @param array $array2
 * @return array
 * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
 * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
 */
function array_merge_recursive_distinct ( array &$array1, array &$array2 )
{
 
$merged = $array1;

  foreach (
$array2 as $key => &$value )
  {
    if (
is_array ( $value ) && isset ( $merged [$key] ) && is_array ( $merged [$key] ) )
    {
     
$merged [$key] = array_merge_recursive_distinct ( $merged [$key], $value );
    }
    else
    {
     
$merged [$key] = $value;
    }
  }

  return
$merged;
}
?>

This fix the E_NOTICE when the the first array doesn't have the key and the second array have a value which is a array.
jonnybergstrom at googles mail domain dot comm
27-Jun-2009 03:30
This function didn't work for me - or it didn't do what I thought it would. So I wrote the below function, which merges two arrays, and returns the resulting array. The base array is the left one ($a1), and if a key is set in both arrays, the right value has precedence. If a value in the left one is an array and also an array in the right one, the function calls itself (recursion). If the left one is an array and the right one exists but is not an array, then the right non-array-value will be used.

*Any key only appearing in the right one will be ignored*
 - as I didn't need values appearing only in the right in my implementation, but if you want that you could make some fast fix.

function array_merge_recursive_leftsource(&$a1, &$a2) {
    $newArray = array();
    foreach ($a1 as $key => $v) {
        if (!isset($a2[$key])) {
            $newArray[$key] = $v;
            continue;
        }

        if (is_array($v)) {
            if (!is_array($a2[$key])) {
                $newArray[$key] = $a2[$key];
                continue;
            }
            $newArray[$key] = array_merge_recursive_leftsource($a1[$key], $a2[$key]);
            continue;
        }

        $newArray[$key] = $a2[$key];
    }
    return $newArray;
}
michiel at synetic dot nl
22-May-2009 08:54
A small improvement upon the previously posted array_merge_recursive_distinct functions (based on daniel's version). This implementation preserves the parameter input from the original, you can pass an infinite amount of array's to merge.

<?php
function &array_merge_recursive_distinct()
{
   
$aArrays = func_get_args();
   
$aMerged = $aArrays[0];
   
    for(
$i = 1; $i < count($aArrays); $i++)
    {
        if (
is_array($aArrays[$i]))
        {
            foreach (
$aArrays[$i] as $key => $val)
            {
                if (
is_array($aArrays[$i][$key]))
                {
                   
$aMerged[$key] = is_array($aMerged[$key]) ? PR::array_merge_recursive_distinct($aMerged[$key], $aArrays[$i][$key]) : $aArrays[$i][$key];
                }
                else
                {
                   
$aMerged[$key] = $val;
                }
            }
        }
    }
   
    return
$aMerged;
}
?>
daniel at danielsmedegaardbuus dot dk
19-Mar-2009 10:18
<?php
/**
 * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
 * keys to arrays rather than overwriting the value in the first array with the duplicate
 * value in the second array, as array_merge does. I.e., with array_merge_recursive,
 * this happens (documented behavior):
 *
 * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('org value', 'new value'));
 *
 * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
 * Matching keys' values in the second array overwrite those in the first array, as is the
 * case with array_merge, i.e.:
 *
 * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
 *     => array('key' => array('new value'));
 *
 * Parameters are passed by reference, though only for performance reasons. They're not
 * altered by this function.
 *
 * @param array $array1
 * @param mixed $array2
 * @return array
 * @author daniel@danielsmedegaardbuus.dk
 */
function &array_merge_recursive_distinct(array &$array1, &$array2 = null)
{
 
$merged = $array1;
 
  if (
is_array($array2))
    foreach (
$array2 as $key => $val)
      if (
is_array($array2[$key]))
       
$merged[$key] = is_array($merged[$key]) ? array_merge_recursive_distinct($merged[$key], $array2[$key]) : $array2[$key];
      else
       
$merged[$key] = $val;
 
  return
$merged;
}
?>
n dot kaiser at online-congress dot com
06-Mar-2009 07:24
Here ist my array recursive merge function
/**
* merge a array recursive
*
* @param array   $array1: original array
* @param array   $array2: the array to insert
* @return array  the merged array
*/
public function recursiveArrayMerge($array1, $array2){
    reset ($array2);
    while(key($array2)!==null) {
        if (is_array(current($array2)) && isset($array1[key($array2)])) {
            $array1[key($array2)] = $this->recursiveArrayMerge($array1[key($array2)],current($array2));
        } else {
            $array1[key($array2)] = current($array2);
        }
        next($array2);
    }
    return $array1;
}
miniscalope at gmail dot com
04-Feb-2009 11:56
I would merge 2 arrays but keep the values unique in the result array.
I hope this will help...
<?php

function array_merge_recursive_unique($array1, $array2) {
   
    foreach(
$array2 AS $k => $v) {
        if(!isset(
$array1[$k]))
        {
           
$array1[$k] = $v;
        }
        else
        {
            if(!
is_array($v)){
                if(
is_array($array1[$k]))
                {
                    if(!
in_array($v,$array1[$k]))
                    {
                       
$array1[$k][] = $v;
                    }
                }
                else
                {
                    if(
$array1[$k] != $v)
                       
$array1[$k] = array($array1[$k], $v);
                 }
            }
            else
            {
               
$array1[$k] =    array_merge_recursive_unique($array1,$array2[$k]);
            }
           
        }
   
    }
      unset(
$k, $v);
      return
$array1;
}

?>
remy dot damour at -please-no-spam-laposte dot net
21-Jan-2009 02:28
If what you want is merge all values of your array that are arrays themselves to get a resulting array of depth one, then you're more looking for array_flatten function.

Unfortunately I did not find such native function in php, here is the one I wrote:

<?php
/**
 * Flatten an array so that resulting array is of depth 1.
 * If any value is an array itself, it is merged by parent array, and so on.
 *
 * @param array $array
 * @param bool $preserver_keys OPTIONAL When true, keys are preserved when mergin nested arrays (=> values with same key get overwritten)
 * @return array
 */
function array_flatten($array, $preserve_keys = false)
{
    if (!
$preserve_keys) {
       
// ensure keys are numeric values to avoid overwritting when array_merge gets called
       
$array = array_values($array);
    }
   
   
$flattened_array = array();
    foreach (
$array as $k => $v) {
        if (
is_array($v)) {
           
$flattened_array = array_merge($flattened_array, call_user_func(__FUNCTION__, $v, $preserve_keys));
        } elseif (
$preserve_keys) {
           
$flattened_array[$k] = $v;
        } else {
           
$flattened_array[] = $v;
        }
    }
    return
$flattened_array;
}

// example
$a = array ('k1' => 'a', 'k2' => array('k1' => 'b', 'k4' => array('k3' => 'c')));
var_export(array_flatten($a)); // output: array(0 => 'a', 1 => 'b', 2 => 'c')
var_export(array_flatten($a, true)); // output: array('k1' => 'b', 'k3' => 'c') // first 'k1' value gets overwritten by nested 'k1' value
?>
phil dot kemmeter at gmail dot com
08-Dec-2008 06:45
I've edit this version even a little bit more, so that the function does not override any values, but inserts them at a free key in the array:

function my_array_merge ($arr,$ins) {
    if(is_array($arr))
    {
        if(is_array($ins)) foreach($ins as $k=>$v)
        {
            if(isset($arr[$k])&&is_array($v)&&is_array($arr[$k]))
            {
                $arr[$k] = my_array_merge($arr[$k],$v);
            }
            else {
                // This is the new loop :)
                while (isset($arr[$k]))
                    $k++;
                $arr[$k] = $v;
            }
        }
    }
    elseif(!is_array($arr)&&(strlen($arr)==0||$arr==0))
    {
        $arr=$ins;
    }
    return($arr);
}

Example:

$array1 = array(
    100 => array(30),
    200 => array(20, 30)
);

$array2 = array(
    100 => array(40),
    201 => array(60, 30)
);

print_r(my_array_merge($array1,$array2));

Output with array_merge_recursive:
Array
(
    [0] => Array
        (
            [0] => 30
        )

    [1] => Array
        (
            [0] => 20
            [1] => 30
        )

    [2] => Array
        (
            [0] => 40
        )

)
This is not the result, I expect from a MERGE-Routine...

Output with the current function:

Array
(
    [100] => Array
        (
            [0] => 30
            [1] => 40
        )

    [200] => Array
        (
            [0] => 20
            [1] => 30
        )

)

This is what I want :)
scott dot clark at vizioninteractive dot com
28-Aug-2008 08:55
Needed some way to fuse two arrays together and found a function here (below from thomas) and decided to update it even further to be a little more smart.

<?php
function my_array_merge ($arr,$ins)
    {
        if(
is_array($arr))
            {
                if(
is_array($ins)) foreach($ins as $k=>$v)
                    {
                        if(isset(
$arr[$k])&&is_array($v)&&is_array($arr[$k]))
                            {
                               
$arr[$k] = my_array_merge($arr[$k],$v);
                            }
                        else
$arr[$k] = $v;
                    }
            }
        elseif(!
is_array($arr)&&(strlen($arr)==0||$arr==0))
            {
               
$arr=$ins;
            }
        return(
$arr);
    }
?>
thomas at n-o-s-p-a-m dot thoftware dot de
05-May-2008 01:50
This is a simple, three line approach.

Short description: If one of the Arguments isn't an Array, first Argument is returned. If an Element is an Array in both Arrays, Arrays are merged recursively, otherwise the element in $ins will overwrite the element in $arr (regardless if key is numeric or not). This also applys to Arrays in $arr, if the Element is scalar in $ins (in difference to the previous approach).

  function array_insert($arr,$ins) {
    # Loop through all Elements in $ins:
    if (is_array($arr) && is_array($ins)) foreach ($ins as $k => $v) {
      # Key exists in $arr and both Elemente are Arrays: Merge recursively.
      if (isset($arr[$k]) && is_array($v) && is_array($arr[$k])) $arr[$k] = array_insert($arr[$k],$v);
      # Place more Conditions here (see below)
      # ...
      # Otherwise replace Element in $arr with Element in $ins:
      else $arr[$k] = $v;
    }
    # Return merged Arrays:
    return($arr);
  }

In Addition to felix dot ospald at gmx dot de in my opinion there is no need to compare keys with type-casting, as a key always is changed into an integer if it could be an integer. Just try

$a = array('1'=>'1');
echo gettype(key($a));

It will echo 'integer'. So for having Integer-Keys simply appended instead of replaced, add the Line:

  elseif (is_int($k)) $arr[] = $v;

A Condition I used is:

  elseif (is_null($v)) unset($arr[$k]);

So a NULL-Value in $ins will unset the correspondig Element in $arr (which is different to setting it to NULL!). This may be another Addition to felix dot ospald at gmx dot de: The absolute correct way to check for a Key existing in an Array is using array_key_exists() (not needed in the current context, as isset() is combined with is_array()). array_key_exists() will return TRUE even if the Value of the Element is NULL.

And the last one: If you want to use this approach for more than 2 Arrays, simply use this:

  function array_insert_mult($arr) {
    # More than 1 Argument: Append all Arguments.
    if (func_num_args() > 1) foreach (array_slice(func_get_args(),1) as $ins) $arr = array_insert($arr,$ins);
    # Return merged Arrays:
    return($arr);
  }

And if you worry about maintaining References: Simply use $ins[$k] instead of $v when assigning a Value/using a Value as Argument.
felix dot ospald at gmx dot de
26-Feb-2008 07:23
If you desire correct and performant behaviour (in contrast to the other postings) use this code. It works as documented above.
If you want that keys are always perserved and not appended or renumbered if they are numeric comment out the "if (((string) $key) === ((string) intval($key)))" case.
@spambegone at cratemedia dot com: using empty is not right way to check if an item is in the array use isset!

<?php

function array_merge_recursive2($array1, $array2)
{
   
$arrays = func_get_args();
   
$narrays = count($arrays);
   
   
// check arguments
    // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array)
   
for ($i = 0; $i < $narrays; $i ++) {
        if (!
is_array($arrays[$i])) {
           
// also array_merge_recursive returns nothing in this case
           
trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning null!', E_USER_WARNING);
            return;
        }
    }
   
   
// the first array is in the output set in every case
   
$ret = $arrays[0];
   
   
// merege $ret with the remaining arrays
   
for ($i = 1; $i < $narrays; $i ++) {
        foreach (
$arrays[$i] as $key => $value) {
            if (((string)
$key) === ((string) intval($key))) { // integer or string as integer key - append
               
$ret[] = $value;
            }
            else {
// string key - megre
               
if (is_array($value) && isset($ret[$key])) {
                   
// if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays)
                    // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be null.
                   
$ret[$key] = array_merge_recursive2($ret[$key], $value);
                }
                else {
                   
$ret[$key] = $value;
                }
            }
        }   
    }
   
    return
$ret;
}

// Examples:

print_r(array_merge_recursive2(array('A','B','C' => array(1,2,3)), array('D','C' => array(1,4))));
/*
Array
(
    [0] => A
    [1] => B
    [C] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
            [3] => 1
            [4] => 4
        )
    [2] => D
)*/

print_r(array_merge_recursive2(array('A','B','0' => array(1,2,3)), array('D','0' => array(1,array(4)))));
/*
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )
    [1] => B
    [2] => Array
        (
            [0] => 1
            [1] => Array
                (
                    [0] => 4
                )
        )
)*/

print_r(array_merge_recursive2(array('A' => array('A' => 1)), array('A' => array('A' => array(2)))));
/*
Warning: Argument #1 is not an array - trying to merge array with scalar! Returning null! in ... on line ...
*/

var_dump(array_merge_recursive2(array('A' => array('A' => 2)), array('A' => array('A' => null))));
/*
array(1) { ["A"]=>  array(1) { ["A"]=>  NULL } }
*/

?>
spambegone at cratemedia dot com
12-Feb-2008 10:06
I've tried these array_merge_recursive functions without much success. Maybe it's just me but they don't seem to actually go more than one level deep? As with all things, its usually easier to write your own, which I did and it seems to work just the way I wanted. Anyways, my function hasn't been tested extensively, but it's a simple function, so in hopes that this might be useful to someone else I'm sharing.

Also, the PHP function array_merge_recursive() didn't work for my purposes because it didn't overwrite the values like I needed it to. You know how it works, it just turns it into an array with multiple values... not helpful if your code is expecting one string.

function array_merge_recursive_unique($array1, $array2) {
   
    // STRATEGY
    /*
    Merge array1 and array2, overwriting 1st array values with 2nd array
    values where they overlap. Use array1 as the base array and then add
    in values from array2 as they exist.
   
    Walk through each value in array2 and see if a value corresponds
    in array1. If it does, overwrite with second array value. If it's an
    array, recursively execute this function and return the value. If it's
    a string, overwrite the value from array1 with the value from array2.
   
    If a value exists in array2 that is not found in array1, add it to array1.
    */

    // LOOP THROUGH $array2
    foreach($array2 AS $k => $v) {
       
        // CHECK IF VALUE EXISTS IN $array1
        if(!empty($array1[$k])) {
            // IF VALUE EXISTS CHECK IF IT'S AN ARRAY OR A STRING
            if(!is_array($array2[$k])) {
                // OVERWRITE IF IT'S A STRING
                $array1[$k]=$array2[$k];
            } else {
                // RECURSE IF IT'S AN ARRAY
                $array1[$k] = array_merge_recursive_unique($array1[$k], $array2[$k]);
            }
        } else {
            // IF VALUE DOESN'T EXIST IN $array1 USE $array2 VALUE
            $array1[$k]=$v;
        }
    }
    unset($k, $v);
   
   
    return $array1;
}
paha at paha dot hu
12-Mar-2007 08:02
In this version the values are overwritten only if they are not an array.  If the value is an array, its elements will be merged/overwritten:

// array_merge_recursive which override value with next value.
// based on: http://www.php.net/manual/hu/function.array-merge-recursive.php 09-Dec-2006 03:38
function array_merge_recursive_unique($array0, $array1)
{
    $arrays = func_get_args();
    $remains = $arrays;

    // We walk through each arrays and put value in the results (without
    // considering previous value).
    $result = array();

    // loop available array
    foreach($arrays as $array) {

        // The first remaining array is $array. We are processing it. So
        // we remove it from remaing arrays.
        array_shift($remains);

        // We don't care non array param, like array_merge since PHP 5.0.
        if(is_array($array)) {
            // Loop values
            foreach($array as $key => $value) {
                if(is_array($value)) {
                    // we gather all remaining arrays that have such key available
                    $args = array();
                    foreach($remains as $remain) {
                        if(array_key_exists($key, $remain)) {
                            array_push($args, $remain[$key]);
                        }
                    }

                    if(count($args) > 2) {
                        // put the recursion
                        $result[$key] = call_user_func_array(__FUNCTION__, $args);
                    } else {
                        foreach($value as $vkey => $vval) {
                            $result[$key][$vkey] = $vval;
                        }
                    }
                } else {
                    // simply put the value
                    $result[$key] = $value;
                }
            }
        }
    }
    return $result;
}
bersace03 at laposte dot net
09-Dec-2006 11:38
Hi all,

Here is a function array_merge_recursive_unique which override values, but walk recursivly arrays and works for unlimited number of arrays. (i posted a previous version which had a bug in recursion).

<?php
// array_merge_recursive which override value with next value.
function array_merge_recursive_unique ($array0, $array1)
{
 
$arrays = func_get_args ();
 
$remains = $arrays;

 
// We walk through each arrays and put value in the results (without
  // considering previous value).
 
$result = array ();

 
// loop available array
 
foreach ($arrays as $array) {

   
// The first remaining array is $array. We are processing it. So
    // we remove it from remaing arrays.
   
array_shift ($remains);

   
// We don't care non array param, like array_merge since PHP 5.0.
   
if (is_array ($array)) {
     
// Loop values
     
foreach ($array as $key => $value) {
    if (
is_array ($value)) {

     
// we gather all remaining arrays that have such key available
     
$args = array ();
      foreach (
$remains as $remain) {
        if (
array_key_exists ($key, $remain)) {
         
array_push ($args, $remain[$key]);
        }
      }
      if (
count ($args) > 2) {
       
// put the recursion
       
$result[$key] = call_user_func_array (__FUNCTION__, $args);
      }
      else {
       
$result[$key] = $value;
      }
    }
    else {

     
// simply put the value
     
$result[$key] = $value;
    }
      }
    }
  }

  return
$result;
}

?>

Enjoy :D
randallgirard at hotmail dot com
26-Nov-2006 09:18
I wrote the following for merging arrays, in my project mainly for configuration... Thought someone else might find it usefull.

function array_merge_recursive_keys( $first, $second, $greedy=false) {
   $inter = array_intersect_assoc(array_keys($first), array_keys($second)); # shaired keys
# the idea next, is to strip and append from $second into $first
   foreach ( $inter as $key ) {
   # recursion if both are arrays
      if ( is_array($first[$key]) && is_array($second[$key]) ) {
         $first[$key] = array_merge_recursive_keys($first[$key], $second[$key]);
      }
   # non-greedy array merging:
      else if ( is_array($first[$key] && !$greedy ) ) {
         $first[$key][] = $second[$key];
      }
      else if ( is_array($second[$key]) && !$greedy ) {
         $second[$key][] = $first[$key];
         $first[$key] = $second[$key];
      }
   # overwrite...
      else {
         $first[$key] = $second[$key];
      }
      unset($second[$key]);
   }
# merge the unmatching keys onto first
   return array_merge($first, $second);
}
thiago dot mata at yahoo dot com dot br
30-Sep-2006 07:25
<?php
   
function array_merge_recursive_keep_keys( $arrElement1 , $arrElement2 , $intCount = 0 )
    {

       
$arrNew = array();
       
       
$arrElement1Keys = array_keys( $arrElement1 );
       
$arrElement2Keys = array_keys( $arrElement2 );
       
       
$arrDifKeys1 = array_diff( $arrElement1Keys, $arrElement2Keys );
       
$arrDifKeys2 = array_diff( $arrElement2Keys, $arrElement1Keys );
       
$arrInter     = array_intersect( $arrElement1Keys , $arrElement2Keys );

        foreach(
$arrDifKeys1 as $strKey1)
        {
           
$arrNew[ $strKey1 ] = $arrElement1[ $strKey1 ];
        }
        foreach(
$arrDifKeys2 as $strKey2)
        {
           
$arrNew[ $strKey2 ] = $arrElement2[ $strKey2 ];
        }
        foreach(
$arrInter as $strInterKey )
        {
            if(
is_array( $arrElement1[ $strInterKey ] ) && is_array( $arrElement2[ $strInterKey ] ) )
            {
               
$intCount++;
               
$arrNew[ $strInterKey ] = array_merge_recursive_keep_keys( $arrElement1[ $strInterKey ] , $arrElement2[ $strInterKey ] , $intCount );
            }
            elseif(
is_array( $arrElement1[ $strInterKey ] ) || is_array( $arrElement2[ $strInterKey ] ) )
            {
               
$arrNew[ $strInterKey ][]    =  $arrElement1[ $strInterKey ];
               
$arrNew[ $strInterKey ][]    =  $arrElement2[ $strInterKey ];
            }
            else
            {
               
$arrNew[ $strInterKey ] = array();
               
$arrNew[ $strInterKey ][] = $arrElement1[ $strInterKey ];
               
$arrNew[ $strInterKey ][] = $arrElement2[ $strInterKey ];
            }
        }
        return
$arrNew;
    }   
?>
smilingrasta
07-Jul-2006 05:04
This function tends to reindex arrays, which is not  mentioned in the function description.

I just tried to run that function on a three dimensional array, containing errormessages.
The first dim. contains the severity of the error ('warn', 'crit') the second dim the linenumber (numerical) and the third one consists of errormessages

<?php
# Array printout:
Array
 (
   [
warn] => Array  // severity (associative)
   
(
      [
2] => Array  // linenumber (numerical)
      
(
         [
0] => "Category does not exist"
        
[1] => "Manufacturer does not exist"
      
)
    )
 )

?>

If i now merge two or more of those arrays using array_merge_recursive(), the linenumbers are not conserved. Instead of, they are all renumbered, starting with 0.

Just thought anyone may want to know about that. :)
regards, smilingrasta
Vladimir Kornea
11-May-2006 02:10
The documentation for array_merge_recursive() states that string keys are preserved while numeric keys are renumbered. What's not obvious is that string keys which happen to be numeric are NOT preserved, but renumbered:

$a = array('5' => array('blue'));
$b = array('5' => array('red'));
$c = array_merge_recursive($a, $b);
print_r($c);

Output:

Array
(
    [0] => Array
        (
            [0] => blue
        )

    [1] => Array
        (
            [0] => red
        )

)

If the key '5' were treated as a string, the resulting array would be this:

Array
(
    [5] => Array
        (
            [0] => blue
            [1] => red
        )
)
jason at ebasterpro dot com
19-Aug-2005 04:56
This modifications allows you to merge arrays of objects and objects of arrays recursively.
/**
 * arrayobj_merge_recursive2()
 *
 * Similar to array_merge_recursive2 but supports objects and arrays, keyed-valued are always overwritten.
 * Priority goes to the 2nd array. And support Object Array mixture
 *
 * @static yes
 * @public yes
 * @param $paArray1 array/object
 * @param $paArray2 array/object
 * @return array/object
 */
function arrayobj_merge_recursive2($paArray1, $paArray2)
{
    if(is_array($paArray2))
    {
        foreach ($paArray2 AS $sKey2 => $sValue2)
        {
            $paArray1[$sKey2] = arrayobj_merge_recursive2(@$paArray1[$sKey2], $sValue2);
        }
    }
    elseif(is_object($paArray2))
    {   
        foreach ($paArray2 AS $sKey2 => $sValue2)
        {
             $paArray1->{$sKey2} = arrayobj_merge_recursive2(@$paArray1->{$sKey2}, $sValue2);
        } 
    } else {
         return $paArray2;
    }  
   return $paArray1;
}
fire at firepages dot com dot au
21-Dec-2004 03:10
PHP5 note , in PHP4 you could pass an uninitialised array to array_merge_recursive which would issue a notice but not break anything ..

while( $whatever){
 $uninitialised_array = array_merge_recursive( $uninitialised_array, $t ) ;
}

in PHP5 , if you dont initialise the array the recursion never starts so $uninitialised_array = array(); solves (good practive anyway I suppose?)
manicdepressive at mindless dot com
22-Jun-2004 02:30
Please be aware that under circumstances where you have
both the key and value common between the two arrays at a given node,
array_merge_recursive() will behave differently if that value is NULL,
as opposed to a non-null value.

i.e., I expected the results of the first two sections below to
have the same structure, but they don't. 
If this might apply to you, please see for yourself.

<pre><?php

$a1
= array('a'=>'b');
$a2 = array('a'=>'b');
$a3 = array_merge_recursive($a1,$a2);
var_export($a3);
echo
"\n\n";

$a1 = array('a'=>NULL);
$a2 = array('a'=>NULL);
$a3 = array_merge_recursive($a1,$a2);
var_export($a3);
echo
"\n\n";

$a1 = array('a'=>'b');
$a2 = array('a'=>NULL);
$a3 = array_merge_recursive($a1,$a2);
var_export($a3);
echo
"\n\n";

?></pre>

This behavior also occurs if the value is the empty array.
In fact, in the above example, interchanging the empty array with
any and all occurences of NULL will yield the same result.

    code till dawn!  -mark
brian at vermonster dot com
25-May-2004 09:44
Here is a fairly simple function that replaces while recursing.

<?php
/**
 * array_merge_recursive2()
 *
 * Similar to array_merge_recursive but keyed-valued are always overwritten.
 * Priority goes to the 2nd array.
 *
 * @static yes
 * @public yes
 * @param $paArray1 array
 * @param $paArray2 array
 * @return array
 */
function array_merge_recursive2($paArray1, $paArray2)
{
    if (!
is_array($paArray1) or !is_array($paArray2)) { return $paArray2; }
    foreach (
$paArray2 AS $sKey2 => $sValue2)
    {
       
$paArray1[$sKey2] = array_merge_recursive2(@$paArray1[$sKey2], $sValue2);
    }
    return
$paArray1;
}

?>

Examples:
<?php

$array1
= array(
   
'liquids' => array(
       
'water' => array('cold', 'fizzy', 'clean')
        ,
'beer' => 'warm'
   
)
);

$array2 = array(
   
'liquids' => array(
       
'water' => 'hot'
       
,'milk' => 'wet'
   
)
);

$result1 = array_merge_recursive2($array1, $array2);
$result2 = array_merge_recursive2($array2, $array1);
?>

Result 1 is:
Array
(
    [liquids] => Array
        (
            [water] => hot
            [beer] => warm
            [milk] => wet
        )
)

Result 2 is:
Array
(
    [liquids] => Array
        (
            [water] => Array
                (
                    [0] => cold
                    [1] => fizzy
                    [2] => clean
                )

            [milk] => wet
            [beer] => warm
        )
)
paska at kios dot sk
04-Mar-2004 10:18
This emulates replace of $_REQUEST according to variable_order=GPC.
<?
    function array_merge_replace($array, $newValues) {
        foreach ($newValues as $key => $value ) {
            if (is_array($value)) {
                if (!isset($array[$key])) {
                    $array[$key] = array();
                }
                $array[$key] = array_merge_replace($array[$key], $value);
            } else {
                $array[$key] = $value;
            }
        }
        return $array;
    }

    $_REQUEST = array_merge_replace($_REQUEST, $_GET);
    $_REQUEST = array_merge_replace($_REQUEST, $_POST);
    $_REQUEST = array_merge_replace($_REQUEST, $_COOKIE);
?>

Useful with stripping backslashes at beginning of main include file:
<?
if (get_magic_quotes_gpc() == 1) {

    function stripMagicSlashes($element) {
        if (is_array($element)) {
            return array_map("stripMagicSlashes", $element);
        } else {
            return stripslashes($element);
        }
    }

    function array_merge_replace($array, $newValues) {
        foreach ($newValues as $key => $value ) {
            if (is_array($value)) {
                if (!isset($array[$key])) {
                    $array[$key] = array();
                }
                $array[$key] = array_merge_replace($array[$key], $value);
            } else {
                $array[$key] = $value;
            }
        }
        return $array;
    }

    $_GET    = array_map("stripMagicSlashes", $_GET);
    $_POST   = array_map("stripMagicSlashes", $_POST);
    $_COOKIE = array_map("stripMagicSlashes", $_COOKIE);

    $_REQUEST = array_merge_replace($_REQUEST, $_GET);
    $_REQUEST = array_merge_replace($_REQUEST, $_POST);
    $_REQUEST = array_merge_replace($_REQUEST, $_COOKIE);

}

$GLOBALS['stripped'] = true;
?>

Based on examples from users from this site.
t dot tom at succont dot de
09-Jan-2004 04:09
Here my modification of shemari's Code for Replacing Values in an Array. My modification will return the new Array, not handle it by reference.
Original Array will not be touched.

Hope it helps anyone. Most thanks goes to shemari ;o)

<?php
  
/**
     * Merges two arrays and replace existing Entrys
     *
     * Merges two Array like the PHP Function array_merge_recursive.
     * The main difference is that existing Keys will be replaced with new Values,
     * not combined in a new Sub Array.
     *
     * Usage:
     *         $newArray = array_merge_replace( $array, $newValues );
     *
     * @access puplic
     * @author Tobias Tom <t.tom@succont.de>
     * @param array $array First Array with 'replaceable' Values
     * @param array $newValues Array which will be merged into first one
     * @return array Resulting Array from replacing Process
     */
function array_merge_replace( $array, $newValues ) {
    foreach (
$newValues as $key => $value ) {
        if (
is_array( $value ) ) {
               if ( !isset(
$array[ $key ] ) ) {
               
$array[ $key ] = array();
            }
           
$array[ $key ] = $this->array_merge_replace( $array[ $key ], $value );
        } else {
            if ( isset(
$array[ $key ] ) && is_array( $array[ $key ] ) ) {
               
$array[ $key ][ 0 ] = $value;
            } else {
                if ( isset(
$array ) && !is_array( $array ) ) {
                   
$temp = $array;
                   
$array = array();
                   
$array[0] = $temp;
                }
               
$array[ $key ] = $value;
            }
        }
    }
    return
$array;
}
?>
shemari75 at mixmail dot com
19-Dec-2003 05:22
Here's a function to recursively merge any number of any-dimensional arrays.
It actually works in quite a similar way as array_merge_recursive does, but with two major differences:
- Later elements overwrite previous ones having the same keys.
- Numeric keys are not appended. Instead, they are converted into associative ones, and therefore overwritten as stated above.

Usage:
    array array_merge_n(array array1, array array2[, array ...])

<?php
   
/**
     *  Merges two arrays of any dimension
     *
     *  This is the process' core!
     *  Here each array is merged with the current resulting one
     *
     *  @access private
     *  @author Chema Barcala Calveiro <shemari75@mixmail.com>
     *  @param array $array   Resulting array - passed by reference
     *  @param array $array_i Array to be merged - passed by reference
     */

   
function array_merge_2(&$array, &$array_i) {
       
// For each element of the array (key => value):
       
foreach ($array_i as $k => $v) {
           
// If the value itself is an array, the process repeats recursively:
           
if (is_array($v)) {
                if (!isset(
$array[$k])) {
                   
$array[$k] = array();
                }
               
array_merge_2($array[$k], $v);

           
// Else, the value is assigned to the current element of the resulting array:
           
} else {
                if (isset(
$array[$k]) && is_array($array[$k])) {
                   
$array[$k][0] = $v;
                } else {
                    if (isset(
$array) && !is_array($array)) {
                       
$temp = $array;
                       
$array = array();
                       
$array[0] = $temp;
                    }
                   
$array[$k] = $v;
                }
            }
        }
    }

   
/**
     *  Merges any number of arrays of any dimension
     *
     *  The arrays to be merged are passed as arguments to the function,
     *  which uses an external function (array_merge_2) to merge each of them
     *  with the resulting one as it's being constructed
     *
     *  @access public
     *  @author Chema Barcala Calveiro <shemari75@mixmail.com>
     *  @return array Resulting array, once all have been merged
     */

   
function array_merge_n() {
       
// Initialization of the resulting array:
       
$array = array();

       
// Arrays to be merged (function's arguments):
       
$arrays =& func_get_args();

       
// Merging of each array with the resulting one:
       
foreach ($arrays as $array_i) {
            if (
is_array($array_i)) {
               
array_merge_2($array, $array_i);
            }
        }

        return
$array;
    }
?>

array_merge> <array_map
Last updated: Fri, 06 Nov 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites