PHP開発において、複数の配列を一つにまとめる操作は非常に頻繁に発生します。
その際、最も一般的に利用される関数がarray_mergeです。
しかし、array_mergeは添字(キー)の種類によって挙動が大きく異なるため、仕様を正しく理解していないと思わぬバグを招くことがあります。
本記事では、array_mergeの基本的な使い方から、実務でハマりやすい注意点、さらには最新のPHPにおける代替手法までを詳しく整理して解説します。
array_merge関数の基本仕様
array_mergeは、1つまたは複数の配列を結合して新しい配列を返す関数です。
基本的な構文は、array_merge(array ...$arrays): arrayとなります。
この関数の最大の特徴は、「後の配列の要素を、前の配列の後ろに追加する」という点にあります。
まずは、最もシンプルな添字配列(インデックス配列)の結合例を見てみましょう。
<?php
$array1 = ['apple', 'banana'];
$array2 = ['orange', 'grape'];
// 配列を結合する
$result = array_merge($array1, $array2);
print_r($result);
Array
(
[0] => apple
[1] => banana
[2] => orange
[3] => grape
)
このように、単純な添字配列の場合は、指定した順番通りに要素が連結されます。
実務で重要となる「キーの重複」による挙動の違い
array_mergeを実務で活用する上で、最も注意しなければならないのが重複するキーが含まれている場合の挙動です。
PHPの配列には「文字列キー」と「数値キー」があり、それぞれで処理ルールが異なります。
文字列キーの場合:後の値で上書きされる
連想配列のように文字列キーを持つ配列を結合する場合、同じキーが存在すると後の配列の値で上書きされます。
これは、設定ファイルのデフォルト値に対して、ユーザー設定を上書きしたい場合などに非常に便利です。
<?php
$defaultConfig = [
'theme' => 'light',
'language' => 'ja',
'debug' => false
];
$userConfig = [
'theme' => 'dark',
'debug' => true
];
$finalConfig = array_merge($defaultConfig, $userConfig);
print_r($finalConfig);
Array
(
[theme] => dark
[language] => ja
[debug] => 1
)
この例では、themeとdebugの値が$userConfigの内容で書き換えられていることがわかります。
数値キーの場合:上書きされず振り直される
一方で、キーが数値である場合は、値が上書きされることはなく、添字が振り直されます。
たとえ明示的に数値キーを指定していても、結果として得られる配列のキーは「0」から順に連続した数値に変換されます。
<?php
$data1 = [100 => 'item A', 101 => 'item B'];
$data2 = [100 => 'item C'];
$result = array_merge($data1, $data2);
print_r($result);
Array
(
[0] => item A
[1] => item B
[2] => item C
)
キー100が重複していますが、item Cは消えることなく、新しいインデックス番号が割り振られています。
この挙動は、IDを保持したい場合には不都合が生じるため注意が必要です。
array_mergeと「+」演算子の違い
PHPには配列を結合するもう一つの方法として、+演算子(配列結合演算子)が存在します。
array_mergeと+演算子では、重複キーの優先順位が真逆になります。
| 特徴 | array_merge | + 演算子 |
|---|---|---|
| 文字列キーの重複 | 後の配列が優先(上書き) | 前の配列が優先(無視) |
| 数値キーの重複 | 振り直して追加 | 前の配列が優先(無視) |
| 主な用途 | リストの結合、設定の上書き | キーを維持したマージ |
数値キーを持つ連想配列で、元のキーを壊さずに欠落している要素だけを補完したい場合は、+演算子を使用するのが適切です。
スプレッド演算子(…)による結合
PHP 7.4以降では、配列内でのスプレッド演算子(...)がサポートされ、PHP 8.1からは文字列キーの配列にも対応しました。
現代的なPHP開発では、array_mergeの代わりにこの記法を用いるケースが増えています。
<?php
$array1 = ['a' => 1];
$array2 = ['b' => 2];
// スプレッド演算子による結合
$result = [...$array1, ...$array2];
print_r($result);
スプレッド演算子を利用するメリットは、関数呼び出しのオーバーヘッドがなく、構文が簡潔になる点にあります。
また、結合の合間に任意の要素を直接挿入できるため、柔軟な配列生成が可能です。
実務でのパフォーマンス上の注意点
大量のデータを扱う際や、ループの中でarray_mergeを使用する場合はパフォーマンスに注意が必要です。
ループ内で繰り返しarray_mergeを実行すると、実行のたびに新しい配列が生成されるため、計算量が爆発的に増加します。
<?php
// パフォーマンスが悪い例
$result = [];
foreach ($masterData as $subArray) {
$result = array_merge($result, $subArray);
}
このような場合は、いったん多次元配列としてデータを集め、最後にスプレッド演算子を使って一度に結合する手法が推奨されます。
<?php
// パフォーマンスが良い例
$allData = [];
foreach ($masterData as $subArray) {
$allData[] = $subArray;
}
$result = array_merge(...$allData);
この書き方により、配列のコピー回数を劇的に減らすことができ、処理速度が大幅に向上します。
再帰的な結合:array_merge_recursive
多次元配列において、ネストされた深い階層まで結合したい場合は、array_merge_recursiveを使用します。
通常のarray_mergeでは、同じキーがあると上の階層が丸ごと上書きされますが、recursive版では子要素もマージ対象となります。
<?php
$array1 = ['form' => ['input' => 'text']];
$array2 = ['form' => ['button' => 'submit']];
$result = array_merge_recursive($array1, $array2);
ただし、同じキーで値がスカラー(文字列や数値)の場合、それらが配列に変換されてまとめられるという特殊な挙動があるため、利用シーンには注意してください。
まとめ
PHPのarray_mergeは非常に強力で便利な関数ですが、キーの種類による挙動の違いを理解しておくことが不可欠です。
文字列キーは上書きされ、数値キーは振り直されるという基本原則を常に意識しましょう。
また、最新のPHP環境ではスプレッド演算子を活用することで、より読みやすく効率的なコードを記述できます。
用途に合わせて、+演算子やarray_merge_recursive、スプレッド演算子を適切に使い分けて、安全な配列操作を実現してください。
