Q:

How to merge two multi dimensional arrays by key value in php?

I have two arrays
$arr1 = [
    ['month' => 1], 
    ['month' => 2], 
    ['month' => 3], 
    ['month' => 4]
];

$arr2 = [
    ['month' => 3, 'info' => 'Alpha'], 
    ['month' => 4, 'info' => 'Beta']
];

I have tried array_merge & array_merge_recursive both are not merging arrays as my expected.
Expected Merging: 
$arr3 = [
    ['month' => 1], 
    ['month' => 2], 
    ['month' => 3, 'info' => 'Alpha'], 
    ['month' => 4, 'info' => 'Beta']
];

Actual with array_merge_recursive is:
$arr3 = array_merge_recursive($arr2, $arr1);
$arr3 = [
    ['month' => 3, 'info' => 'Alpha'], 
    ['month' => 4, 'info' => 'Beta']
    ['month' => 1], 
    ['month' => 2], 
    ['month' => 3], 
    ['month' => 4]
];

A:

If the arrays are associative on month then you can use array_replace.
First make the arrays associative with array_column then replace $arr1 with $arr2 values.
$arr1 = [
    ['month' => 1], 
    ['month' => 2], 
    ['month' => 3], 
    ['month' => 4]
];

$arr2 = [
    ['month' => 3, 'info' => 'Alpha'], 
    ['month' => 4, 'info' => 'Beta'],
    ['month' => 1, 'info' => 'Gamma'],
];

$arr1 = array_column($arr1, null, 'month');
$arr2 = array_column($arr2, null, 'month');

$result = array_replace($arr1, $arr2);
var_dump($result);

Returns:
array(4) {
  [1]=>
  array(2) {
    ["month"]=>
    int(1)
    ["info"]=>
    string(5) "Gamma"
  }
  [2]=>
  array(1) {
    ["month"]=>
    int(2)
  }
  [3]=>
  array(2) {
    ["month"]=>
    int(3)
    ["info"]=>
    string(5) "Alpha"
  }
  [4]=>
  array(2) {
    ["month"]=>
    int(4)
    ["info"]=>
    string(4) "Beta"
  }
}

https://3v4l.org/tpshB
If you have older version of PHP which does not have array_column then you can use this legacy code from manual
if (!function_exists('array_column')) {
    function array_column($array, $columnKey, $indexKey = null)
    {
        $result = array();
        foreach ($array as $subArray) {
            if (is_null($indexKey) && array_key_exists($columnKey, $subArray)) {
                $result[] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
            } elseif (array_key_exists($indexKey, $subArray)) {
                if (is_null($columnKey)) {
                    $index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                    $result[$index] = $subArray;
                } elseif (array_key_exists($columnKey, $subArray)) {
                    $index = is_object($subArray)?$subArray->$indexKey: $subArray[$indexKey];
                    $result[$index] = is_object($subArray)?$subArray->$columnKey: $subArray[$columnKey];
                }
            }
        }
        return $result;
    }
}

A:

In this case, I walk the arrays and construct the desired output.
$output = [];
$allMerged = array_merge($arr1, $arr2);
array_walk($allMerged, 
  function($item, $key) use (&$output) {
    print_r($item);
    if ( array_key_exists($item['month'], $output) ) {
        if ( isset($item['info']) ) {
            $output[$item['month']]['info'] = $item['info'];
        } else {
            $output[$item['month']] = $item;
        }
    } else {
        $output[$item['month']] = $item;
    }
});
print_r($output);

