階層構造を持つ配列のマージ

### 環境
PHP7

### やりたかったこと

階層のある配列どうしをマージしたかった。

```php
$a = [
    'a' => 1,
    'b' => [
        'c' => 2,
        'd' => [
            'e' => 3,
            'f' => [
            ]
        ]
    ]
];

$b = [
    'b' => [
        'c' => 6,
        'd' => [
            'f' => [
                'g' => 4
            ]
        ]
    ]
];
function merge_function($a,$b)
{
    // なにがしかの処理
}
print_r(merge_function($a,$b));
```

期待される結果

```:php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 6
            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)
```

↑要は、既にある要素は上書き、ない要素は追加を各階層ごとに行うって感じです。

過去記事もちょっと探してみたものの、それらしいことをやっている記事が見つかりませんでした。余り需要がないってことでしょうか。

### やってみたこと

## 1）array_merge

```php
function merge_function($a,$b)
{
    return array_merge($a,$b);
}
print_r(merge_function($a,$b));
```

結果↓

```:php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 6
            [d] => Array
                (
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)
```
第3階層がダメですね。

## 2）array_merge_recursive

```php
function merge_function($a,$b)
{
    return array_merge_recursive($a,$b);
}
print_r(merge_function($a,$b));
```

結果↓

```:php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => Array
                (
                    [0] => 2
                    [1] => 6
                )

            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)
```
第2階層のcが配列に変化してしまってます。

## 3）配列結合演算子(+)

```php
function merge_function($a,$b)
{
    return $a + $b;
}
print_r(merge_function($a,$b));
```

結果↓

```:php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 2
            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                        )
                )
        )
)
```
c、gが上書きできていません。

## 4)関数で自作

```:php
function merge_left(array $a,array $b)
{
    $merged_keys = [];
    foreach($a as $k => $v){
        if (isset($b[$k])){
            if (is_array($a[$k]) && is_array($b[$k])){
                $a[$k] = merge_left($a[$k],$b[$k]);
            }
            else{
                $a[$k] = $b[$k];
            }
            $merged_keys[] = $k;
        }
    }
    foreach($b as $k => $v){
        if (!in_array($k,$merged_keys,true)){
            $a[$k] = $b[$k];
        }
    }
    return $a;
}
function merge_function($a,$b)
{
    return merge_left($a,$b);
}
print_r(merge_function($a,$b));
```

結果↓

```:php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 6
            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)
```
バグがありそうだけど、なんとなく良さそう！

### 思ったこと

- ~~do not trust PHP standard functions!~~ Read PHP Manual carefully!
- in_arrayは罠
- ~~もっといいやり方があったらコメントが欲しいです・・・(･ε･｡)ﾏｼﾞﾃﾞ~~ ありました！感謝！