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… と振り直されます。そのため、同じ数値キーを持っていても上書きされず、すべての要素が残ります。
<?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つの要素がすべて残っています。リストをつなげたいときの定番の挙動です。
文字列キーは後ろの配列が優先(後勝ち)
一方、文字列キーの場合はキーが振り直されません。同じキーがぶつかると、後ろに渡した配列の値で上書きされます。これを「後勝ち」と覚えておくと分かりやすいです。
<?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 の値「青」が残りました。重複しないキー(size と price)はそのまま両方とも保持されます。
+ 演算子(union)で結合する
配列は + 演算子でも結合できます。これは「union(和集合)演算子」と呼ばれ、array_merge() とは逆の発想で動きます。$a + $b と書いたとき、キーが衝突したら先に書いた $a の値を優先(先勝ち)し、$b にしかないキーだけが追加されます。数値キーであっても振り直しは行いません。
<?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() とは結果が大きく変わります。キーが振り直されないため、同じキー(位置)を持つ要素は先の配列が優先され、後ろの配列の同じ位置の要素は無視されてしまうからです。
<?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() が向いています。
<?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引数が値になります。
<?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() は後勝ち・数値キーは振り直し、+ は先勝ち・キーはそのまま、という対の関係を押さえておけば、配列の結合で迷うことはなくなります。