【PHP8.x】array_merge_recursive関数の使い方

作成日: 更新日:

array_merge_recursive関数は、一つまたは複数の配列を再帰的にマージする関数です。この関数は、入力として与えられた複数の配列を結合し、一つの配列として返します。もし同じキーが複数の配列に存在する場合、array_merge_recursiveは値を上書きするのではなく、それらの値を配列として再帰的にマージします。数値キーの場合、array_merge_recursiveは後続の配列の値を既存の配列に追加します。ただし、キーが文字列の場合、同じキーを持つ値は配列にマージされます。

具体的には、入力配列に同じ文字列キーが存在する場合、そのキーに対応する値が両方とも配列であれば、array_merge_recursiveはその二つの配列を再帰的にマージします。もし値が配列でない場合は、両方の値が配列に格納され、その配列が結果配列のキーに対応する値となります。数値キーの場合、array_merge_recursiveはキーを再インデックスせずに、後続の配列の値を結果配列に追加します。

この関数は、複数の設定ファイルやデータ構造を組み合わせる際に特に役立ちます。例えば、デフォルト設定とユーザー設定をマージして、最終的な設定を生成する場合などに利用できます。ただし、深いネスト構造を持つ配列をマージする際には、メモリ使用量に注意する必要があります。array_merge_recursiveは、元の配列を変更せず、新しい配列を返すため、元のデータを保持したままマージ結果を利用できます。

基本的な使い方

構文(syntax)

array_merge_recursive ( array ...$arrays ) : array

引数(parameters)

array ...$arrays

  • array ...$arrays: マージしたい配列を可変長で指定します。複数の配列をカンマ区切りで指定できます。

戻り値(return)

array

複数の配列を再帰的にマージした新しい配列を返します。キーが重複した場合、値は配列としてまとめられます。

サンプルコード

PHP array_merge_recursive でキーを保持してマージする

<?php

/**
 * array_merge_recursive() の挙動を示すサンプルコード。
 * キーが同じ場合、値を再帰的にマージします。
 * 数値キーの場合は、値が重複して追加されます。
 */

$array1 = [
    'color' => ['favorite' => 'red'],
    5,
];

$array2 = [
    10,
    'color' => ['favorite' => 'green', 'blue'],
];

$result = array_merge_recursive($array1, $array2);

print_r($result);
/*
出力結果:
Array
(
    [color] => Array
        (
            [favorite] => Array
                (
                    [0] => red
                    [1] => green
                )

            [0] => blue
        )

    [0] => 5
    [1] => 10
)
*/

/**
 * キーを保持してマージしたい場合は、ループ処理で実装する必要がある。
 */
function array_merge_keep_keys(array ...$arrays): array
{
    $result = [];
    foreach ($arrays as $array) {
        foreach ($array as $key => $value) {
            if (is_int($key)) {
                $result[] = $value;
            } elseif (is_array($value) && isset($result[$key]) && is_array($result[$key])) {
                $result[$key] = array_merge_keep_keys($result[$key], $value);
            } else {
                $result[$key] = $value;
            }
        }
    }
    return $result;
}

$array3 = [
    'color' => ['favorite' => 'red'],
    5,
];

$array4 = [
    10,
    'color' => ['favorite' => 'green', 'blue'],
];

$result2 = array_merge_keep_keys($array3, $array4);

print_r($result2);

/*
出力結果
Array
(
    [color] => Array
        (
            [favorite] => green
            [0] => blue
        )

    [0] => 5
    [1] => 10
)
*/

array_merge_recursive()関数は、複数の配列を再帰的にマージするPHPの組み込み関数です。引数には、マージしたい配列を可変長引数として渡します。戻り値は、マージされた新しい配列です。

この関数は、キーが同じ要素が存在する場合に、その値を再帰的にマージします。もし、同じキーの値が配列同士だった場合は、さらにそれらの配列をマージします。キーが数値の場合は、array_merge()関数と同様に、値が単純に追加され、キーは連番で振り直されます。

サンプルコードでは、$array1$array2という2つの配列をarray_merge_recursive()でマージしています。$array1'color'キーと$array2'color'キーは両方とも配列であるため、それらの配列が再帰的にマージされます。数値キーの 510 は、新しい配列の [0][1] にそれぞれ追加されています。

一方、キーを保持してマージしたい場合は、array_merge_recursive()関数では実現できません。サンプルコードでは、array_merge_keep_keys()というユーザー定義関数で、キーを保持したまま配列を再帰的にマージする例を示しています。この関数では、is_int()関数でキーが数値かどうかを判定し、数値キーの場合は単純に値を追加します。キーが文字列で、かつ値が配列の場合は、再帰的にarray_merge_keep_keys()を呼び出してマージを行います。$array3$array4array_merge_keep_keys()でマージした結果は、キーが保持され、'color'キーの値が上書きされていることがわかります。

array_merge_recursive()関数は、同じキーを持つ配列を再帰的にマージする際に、数値キーの場合、値が単純に追加される点に注意が必要です。文字列キーが重複する場合は、値が配列としてマージされます。もしキーを保持して上書きするようなマージ処理を行いたい場合は、サンプルコードにあるarray_merge_keep_keys()のような独自の関数を実装する必要があります。この関数は、キーが数値の場合は単純に追加し、文字列キーの場合は値を上書きします。array_merge_recursive()array_merge_keep_keys()は挙動が異なるため、目的に応じて使い分けるようにしてください。また、PHPのバージョンによっては動作が異なる可能性があるので、使用する環境での動作確認を推奨します。

PHP array_merge_recursive 再帰結合する

<?php

/**
 * array_merge_recursive 関数の動作を示すサンプルコードです。
 *
 * この関数は複数の配列を再帰的に結合します。
 * 'overwrite' というキーワードに対する重要な点は、
 * 同じ文字列キーを持つ要素があった場合、新しい値で既存の値を上書きするのではなく、
 * 両方の値を新しい配列として結合する点です。
 * 数値キーを持つ要素は、単純に追加されます。
 */
function demonstrateArrayMergeRecursive(): void
{
    // 最初の配列を定義します。
    $array1 = [
        'fruit' => 'apple',
        'colors' => ['red', 'green'],
        'details' => [
            'origin' => 'Japan',
            'taste' => 'sweet',
        ],
        0 => 'item_from_array1_index0',
    ];

    // 2番目の配列を定義します。
    // $array1 と同じキーを持つ要素が含まれています。
    $array2 = [
        'fruit' => 'orange', // 'fruit' キーは $array1 にも存在
        'colors' => ['blue'], // 'colors' キーは $array1 にも存在
        'details' => [
            'taste' => 'sour', // 'details' の中の 'taste' キーは $array1 にも存在
            'season' => 'summer', // 新しいキー
        ],
        0 => 'item_from_array2_index0', // 数値キー0は $array1 にも存在
    ];

    echo "--- 元の配列 ---" . PHP_EOL;
    echo "配列 1:" . PHP_EOL;
    print_r($array1);
    echo "配列 2:" . PHP_EOL;
    print_r($array2);
    echo PHP_EOL;

    // array_merge_recursive を使用して配列を結合します。
    // 同じ文字列キーを持つ要素がどのように扱われるかに注目してください。
    $mergedArray = array_merge_recursive($array1, $array2);

    echo "--- array_merge_recursive の結果 ---" . PHP_EOL;
    print_r($mergedArray);
    echo PHP_EOL;

    echo "--- 'overwrite' に関する補足 ---" . PHP_EOL;
    echo "結果を確認すると、'fruit' キーの値は 'orange' で上書きされず、" . PHP_EOL;
    echo "['apple', 'orange'] という新しい配列として結合されていることがわかります。" . PHP_EOL;
    echo "同様に、ネストされた配列の 'details' -> 'taste' も上書きされず、" . PHP_EOL;
    echo "['sweet', 'sour'] として結合されています。" . PHP_EOL;
    echo "数値キー (例: 0) の要素は単純に追加され、新しいインデックスが割り当てられます。" . PHP_EOL;
}

// 関数を実行します。
demonstrateArrayMergeRecursive();

PHPのarray_merge_recursive関数は、複数の配列を再帰的に結合するために利用される拡張機能です。この関数は引数として結合したい複数の配列を受け取り、それらを結合した新しい配列を返します。

この関数の大きな特徴は、同じ文字列キーを持つ要素があった場合の挙動です。通常、配列の結合では後から来た値が前の値を上書き(overwrite)することがありますが、array_merge_recursiveでは値を上書きせず、同じキーの値を新しい配列として結合します。例えば、'fruit' => 'apple''fruit' => 'orange' がある場合、結合結果は'fruit' => ['apple', 'orange'] のようになります。この再帰的な結合は、ネストされた配列に対しても適用されます。一方で、数値キーを持つ要素は、同じキーがあったとしても単純に結合後の配列に追加されます。

このため、既存の値を上書きすることなく、共通のキーに関連するすべての値を新しい配列として保持したい場合に特に有用です。

array_merge_recursive関数は、複数の配列を再帰的に結合します。この関数の最も重要な注意点は、キーが重複した場合の挙動です。同じ文字列キーを持つ要素があった場合、後の配列の値で前の配列の値が上書きされるのではなく、両方の値が新しい配列として結合されます。これはネストされた配列に対しても同様です。一方、同じ数値キーを持つ要素は上書きされず、単純に末尾に追加されます。この「上書きではなく結合」という動作を理解せず利用すると、意図しないデータ構造が生成される可能性があります。特に文字列キーの結合ロジックを把握しておくことが、本関数を安全かつ正しく利用するための重要なポイントです。

【PHP8.x】array_merge_recursive関数の使い方 | いっしー@Webエンジニア