Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Array Functions : array_merge_recursive

array_merge_recursive

Merge two or more arrays recursively (PHP 4 >= 4.0.1, PHP 5)
array array_merge_recursive ( array array1 [, array ...] )

array_merge_recursive() merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.

If the input arrays have the same string keys, then the values for these keys are merged together into an array, and this is done recursively, so that if one of the values is an array itself, the function will merge it with a corresponding entry in another array too. If, however, the arrays have the same numeric key, the later value will not overwrite the original value, but will be appended.

Parameters

array1

Initial array to merge.

array

Variable list of arrays to recursively merge.

Return Values

An array of values resulted from merging the arguments together.

Examples

Example260.array_merge_recursive() example

<?php
$ar1
= array("color" => array("favorite" => "red"), 5);
$ar2 = array(10, "color" => array("favorite" => "green", "blue"));
$result = array_merge_recursive($ar1, $ar2);
print_r($result);
?>

The above example will output:

Array
(
[
color] => Array
(
[
favorite] => Array
(
[
0] => red
[1] => green
)

[
0] => blue
)

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


See Also
array_merge()

Related Examples ( Source code ) » array_merge_recursive


Code Examples / Notes » array_merge_recursive

jason

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;
}


smilingrasta

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


paska

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.


vladimir kornea

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
       )
)


mikeo

Similarly, you can cast variables to type array.  This is especially useful if you're passing arrays by reference.
function addHeader(&$lArray, $description = null)
{
  ...
  $lArray = array_merge_recursive((array)$lArray, $tmpArray);
  ...
}


manicdepressive

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


fire

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?)


paha

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;
}


randallgirard

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);
}


bersace03

Hi all,
I wrote a array_merge_recursive_unique which do exactly like array_merge_recursive2 but allow infinity of arrays as argument.
<?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]);
   }
 }
 // put the recursion
 $result[$key] = call_user_func_array (__FUNCTION__, $args);
}
else {
 // simply put the value
 $result[$key] = $value;
}
     }
   }
 }
 return $result;
}
?>
Enjoy :)


shemari75

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;
   }
?>


t dot tom

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;
}
?>


brian

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
       )
)


thiago dot mata

<?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;
}
?>


Change Language


Follow Navioo On Twitter
array_change_key_case
array_chunk
array_combine
array_count_values
array_diff_assoc
array_diff_key
array_diff_uassoc
array_diff_ukey
array_diff
array_fill_keys
array_fill
array_filter
array_flip
array_intersect_assoc
array_intersect_key
array_intersect_uassoc
array_intersect_ukey
array_intersect
array_key_exists
array_keys
array_map
array_merge_recursive
array_merge
array_multisort
array_pad
array_pop
array_product
array_push
array_rand
array_reduce
array_reverse
array_search
array_shift
array_slice
array_splice
array_sum
array_udiff_assoc
array_udiff_uassoc
array_udiff
array_uintersect_assoc
array_uintersect_uassoc
array_uintersect
array_unique
array_unshift
array_values
array_walk_recursive
array_walk
array
arsort
asort
compact
count
current
each
end
extract
in_array
key
krsort
ksort
list
natcasesort
natsort
next
pos
prev
range
reset
rsort
shuffle
sizeof
sort
uasort
uksort
usort
eXTReMe Tracker