PHP
Deep Merge Multiple Associative Arrays Recursively
Implement a robust function to recursively merge multiple associative PHP arrays, handling nested structures gracefully for configurations, default options, or API responses.
<?php
function array_merge_recursive_distinct(array ...$arrays): array {
$base = array_shift($arrays);
if (!is_array($base)) return $base; // Handle non-array first argument
foreach ($arrays as $array) {
if (!is_array($array)) continue; // Skip non-array arguments
foreach ($array as $key => $value) {
if (isset($base[$key]) && is_array($base[$key]) && is_array($value)) {
$base[$key] = array_merge_recursive_distinct($base[$key], $value);
} else {
$base[$key] = $value;
}
}
}
return $base;
}
$configDefault = [
'database' => [
'host' => 'localhost',
'user' => 'root',
'password' => ''
],
'app' => [
'name' => 'My App',
'debug' => true,
'features' => ['search', 'notifications']
]
];
$configProduction = [
'database' => [
'user' => 'produser',
'password' => 'secure_pass',
'port' => 3306
],
'app' => [
'debug' => false,
'features' => ['search', 'billing'] // Overwrites default entirely, for merging features custom logic might be needed
]
];
$mergedConfig = array_merge_recursive_distinct($configDefault, $configProduction);
print_r($mergedConfig);
/* Output:
Array
(
[database] => Array
(
[host] => localhost
[user] => produser
[password] => secure_pass
[port] => 3306
)
[app] => Array
(
[name] => My App
[debug] =>
[features] => Array
(
[0] => search
[1] => billing
)
)
)*/
How it works: The `array_merge_recursive_distinct` function provides a more controlled deep merge compared to PHP's native `array_merge_recursive`. It takes multiple arrays and merges them recursively. When a key exists in both arrays and its values are both arrays, it calls itself to merge those nested arrays. Otherwise, the value from the later array in the argument list overwrites the value from the earlier array. This is extremely useful for managing configurations, where you have a set of defaults and want to overlay environment-specific or user-defined settings without losing nested structures.