If you’ve been coding in PHP for a while, you have probably used
array_merge()
at some point. It’s been around since PHP 4, and like most PHP
functions, it does largely what you’d expect it to do. If you have
arrays with numeric indices, it re-indexes and appends subsequent arrays
to the first array argument.
print_r( array_merge (
array ( 'a' , 'b' ),
array ( 'c' , 'd' )
));
|
If you have associative arrays, it doesn’t make much sense to re-index them. Instead, non-numeric keys are … well,
merged. Keys from subsequent arrays will overwrite keys with the same name in earlier arrays.
print_r( array_merge (
array ( 'A' => 1, 'B' => 2),
array ( 'B' => 20, 'C' => 30)
));
|
This is all pretty intuitive. But it gets trickier when you have
nested associative arrays to merge. For example, you may have decoded
the results from two JSON service calls into arrays, and they both have a
top-level
data
key.
array_merge()
is not as useful in this case:
print_r( array_merge (
array (
'data' => array (
'collision' => 'first' ,
'unique1' => 1,
)
),
array (
'data' => array (
'collision' => 'second' ,
'unique2' => 2,
)
)
));
|
The first array got clobbered — not quite what you expected, right?
Fortunately, there’s a function that will do what you probably want:
array_merge_recursive()
.
print_r( array_merge_recursive (
array (
'data' => array (
'collision' => 'first' ,
'unique1' => 1,
)
),
array (
'data' => array (
'collision' => 'second' ,
'unique2' => 2,
)
)
));
|
In some cases, this behavior isn’t actually what you want. One
example is parsing hierarchical config files. If you had a default
config and you wanted to merge in a user-specific config, you probably
don’t want keys to be merged the way
array_merge_recursive()
does it. Instead, you would want the user-specific config to replace
the default config’s value for that particular key. If you’re running
PHP before version 5.3, you’d have to write a custom function to do
this. But as of PHP 5.3, there is a new function that does exactly what
you want:
array_replace_recursive()
.
print_r(array_replace_recursive(
array (
'data' => array (
'collision' => 'first' ,
'unique1' => 1,
)
),
array (
'data' => array (
'collision' => 'second' ,
'unique2' => 2,
)
)
));
|
If you’ve written a custom version of
array_replace_recursive()
and would like to switch to the built-in version, one helpful commenter suggests replacing your custom version with a wrapper that just calls
array_replace_recursive()
. There are also a few pure-PHP implementations of
array_replace_recursive()
if you’re stuck with an older version of PHP.