1. ホーム
  2. PHP

【PHP】array_merge と + 演算子で配列を結合する方法|違いと使い分けを解説

Share

PHP で複数の配列を1つにまとめたい場面は、設定値の合成やデータの連結などで頻繁に登場します。配列の結合には主に array_merge() 関数と +(union)演算子の2つがあり、見た目は似ていても挙動がはっきり異なります。この記事では、両者の違いを「数値キーの扱い」「キーが衝突したときどちらが残るか」という観点から具体例で解説し、最後に array_combine() による連想配列の作り方にも軽く触れます。

配列の結合に2つの方法がある理由

PHP の配列は「添字配列(0, 1, 2… という連番のキー)」と「連想配列(文字列のキー)」が同じ仕組みで扱えます。そのため、配列を結合するときに「連番は振り直したいのか」「同じキーがぶつかったらどちらを優先したいのか」という判断が必要になります。array_merge()+ 演算子は、この判断のしかたが違うため、用途に応じて使い分けます。まずはそれぞれの基本から見ていきましょう。

array_merge() の基本的な使い方

array_merge() は、渡した複数の配列を順番につなげて1つの配列を返す関数です。挙動はキーの種類によって変わります。数値キー(添字配列)は0から振り直されて連結され、文字列キーは同じキーがあれば後ろの配列の値で上書きされます。

添字配列はキーが0から振り直される

数値キーの配列同士を結合すると、元のキーの値は無視され、先頭から 0, 1, 2… と振り直されます。そのため、同じ数値キーを持っていても上書きされず、すべての要素が残ります。

merge_numeric.php
<?php
$a = ['りんご', 'みかん'];      // キーは 0, 1
$b = ['ぶどう', 'もも'];        // キーは 0, 1

$result = array_merge($a, $b);
print_r($result);
// Array
// (
//     [0] => りんご
//     [1] => みかん
//     [2] => ぶどう
//     [3] => もも
// )

$a$b もキーは 0, 1 ですが、結合後はキーが 0〜3 に振り直され、4つの要素がすべて残っています。リストをつなげたいときの定番の挙動です。

文字列キーは後ろの配列が優先(後勝ち)

一方、文字列キーの場合はキーが振り直されません。同じキーがぶつかると、後ろに渡した配列の値で上書きされます。これを「後勝ち」と覚えておくと分かりやすいです。

merge_string.php
<?php
$a = ['color' => '赤', 'size' => 'M'];
$b = ['color' => '青', 'price' => 1000];

$result = array_merge($a, $b);
print_r($result);
// Array
// (
//     [color] => 青      // $b の値で上書きされた
//     [size]  => M
//     [price] => 1000
// )

color キーが両方にあるため、後ろの $b の値「青」が残りました。重複しないキー(sizeprice)はそのまま両方とも保持されます。

+ 演算子(union)で結合する

配列は + 演算子でも結合できます。これは「union(和集合)演算子」と呼ばれ、array_merge() とは逆の発想で動きます。$a + $b と書いたとき、キーが衝突したら先に書いた $a の値を優先(先勝ち)し、$b にしかないキーだけが追加されます。数値キーであっても振り直しは行いません。

union.php
<?php
$a = ['color' => '赤', 'size' => 'M'];
$b = ['color' => '青', 'price' => 1000];

$result = $a + $b;
print_r($result);
// Array
// (
//     [color] => 赤      // 先の $a が優先された
//     [size]  => M
//     [price] => 1000
// )

同じ color キーでも、今度は先の $a の「赤」が残りました。+ は「足りないキーを補う」イメージで、すでにあるキーは決して上書きしないのが特徴です。

数値キーでも振り直されないので注意

添字配列を + で結合すると、array_merge() とは結果が大きく変わります。キーが振り直されないため、同じキー(位置)を持つ要素は先の配列が優先され、後ろの配列の同じ位置の要素は無視されてしまうからです。

union_numeric.php
<?php
$a = ['りんご', 'みかん'];   // キーは 0, 1
$b = ['ぶどう', 'もも'];     // キーは 0, 1

$result = $a + $b;
print_r($result);
// Array
// (
//     [0] => りんご   // キー 0 は $a が優先
//     [1] => みかん   // キー 1 も $a が優先
// )
// $b の 'ぶどう' と 'もも' は同じキーなので捨てられる

array_merge() なら4要素になったのに対し、+ では2要素しか残りません。リストを連結するつもりで + を使うと、要素が消えて気づきにくいバグになります。添字配列の連結には array_merge() を使うのが基本です。

array_merge と + 演算子の違いを整理する

ここまでの挙動を表にまとめます。「数値キーをどう扱うか」「同じキーが衝突したときどちらを残すか」の2点が決定的な違いです。

観点array_merge()+ 演算子(union)
数値キーの扱い0から振り直して連結振り直さない(元のキーを維持)
数値キーが衝突したとき振り直すので両方残る先の配列が優先(後ろは無視)
文字列キーが衝突したとき後ろの配列が優先(後勝ち)先の配列が優先(先勝ち)
書き方array_merge($a, $b)$a + $b

ざっくり言えば、添字配列をつなげたいなら array_merge()、連想配列で「足りない値だけ補いたい」なら + と覚えると選びやすくなります。

実践例:デフォルト設定とユーザー設定をマージする

配列の結合がよく使われるのが、設定値のマージです。あらかじめ用意したデフォルト設定に、ユーザーが指定した一部の設定だけを上書き反映したい、という場面を考えます。ここでは「ユーザーが指定した値を優先したい」ので、後勝ちの array_merge() が向いています。

settings.php
<?php
// デフォルト設定
$defaults = [
    'theme'    => 'light',
    'per_page' => 10,
    'sidebar'  => true,
];

// ユーザーが指定した設定(一部だけ)
$userConfig = [
    'theme'    => 'dark',
    'per_page' => 20,
];

// ユーザー設定を後ろに置いて上書きさせる
$config = array_merge($defaults, $userConfig);
print_r($config);
// Array
// (
//     [theme]    => dark   // ユーザー指定が優先
//     [per_page] => 20     // ユーザー指定が優先
//     [sidebar]  => 1      // 指定がないのでデフォルト
// )

逆に「デフォルトはあくまで初期値として、ユーザー値を最優先しつつ未指定だけ補いたい」なら $userConfig + $defaults と書く手もあります。+ は先勝ちなので、ユーザー設定を先に置くのがポイントです。どちらの方法でも結果は同じになりますが、文字列キー中心の設定マージでは array_merge() の方が読み手に意図が伝わりやすいでしょう。

array_combine() でキー配列と値配列から連想配列を作る

「結合」と聞いて関連する関数に array_combine() があります。これは複数の配列を縦につなげるのではなく、キーの配列と値の配列を組み合わせて1つの連想配列を作る関数です。第1引数がキー、第2引数が値になります。

combine.php
<?php
$keys   = ['name', 'age', 'city'];
$values = ['田中', 28, '東京'];

$person = array_combine($keys, $values);
print_r($person);
// Array
// (
//     [name] => 田中
//     [age]  => 28
//     [city] => 東京
// )

CSV のヘッダー行を $keys、データ行を $values として渡すと、列名付きのデータに変換できる、といった使い方ができます。なお、2つの配列の要素数が一致していないと PHP 8.0 以降では ValueError が投げられるため、件数をそろえてから渡す点には注意してください。

結合結果が期待とずれるときに見直すこと

配列の結合は挙動を取り違えると、要素が消えたりキーがずれたりして気づきにくいバグになります。よくあるつまずきを2つ取り上げます。

+ で結合したら要素が消えた

添字配列を + で結合して「要素が増えていない」場合、原因はほぼキーの衝突です。+ は同じキーがあれば先の配列を優先し、後ろの同じキーの要素を捨てます。番号付きのリストを単純につなげたいだけなら、キーを振り直してくれる array_merge() に置き換えるのが正解です。「結合=+」と早合点せず、扱っているのが添字配列か連想配列かをまず確認しましょう。

どちらの値が残るか分からなくなる

キーが衝突したときに「結局どちらの値が残るのか」で混乱しがちです。array_merge($a, $b)後ろの $b が勝ち、$a + $b先の $a が勝ちます。優先したい配列を、array_merge() なら後ろに、+ なら前に置く、と逆になる点を意識すると間違えにくくなります。設定マージのように「上書きされる側」と「上書きする側」がはっきりしている場面では、コメントで意図を書き添えておくと後から読んでも安心です。

まとめ

PHP の配列結合は、扱う配列の種類と「どちらを優先したいか」で方法を選びます。

  • 添字配列を連結したい(キーを振り直したい) → array_merge()
  • 連想配列で後ろの値を優先したい(後勝ち) → array_merge()
  • 連想配列で先の値を優先し、足りないキーだけ補いたい(先勝ち) → + 演算子
  • キーの配列と値の配列から連想配列を作りたい → array_combine()

array_merge() は後勝ち・数値キーは振り直し、+ は先勝ち・キーはそのまま、という対の関係を押さえておけば、配列の結合で迷うことはなくなります。

参考ページ