はじめに
PHPでは ...(スプレッド演算子)を使った 配列アンパック(Array Unpacking) が利用できます。これを使いこなすと、配列のマージや関数への引数展開がシンプルかつ直感的に書けるようになります。
PHP 5.6 で関数の引数展開に、PHP 7.4 でリテラル配列のアンパックに対応し、PHP 8.1 では文字列キーを持つ配列へのスプレッドにも対応しました。本記事では基本から実践的なパターンまで順を追って解説します。
基本:スプレッド演算子とは
スプレッド演算子 ... を配列の前に付けると、配列の要素を「展開」できます。
<?php
$a = [1, 2, 3];
$b = [4, 5, 6];
$merged = [...$a, ...$b];
print_r($merged);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )
array_merge() を使わなくても、直感的に配列を結合できます。
関数の引数に配列を展開する
スプレッド演算子は、関数の引数として配列を渡す場面でも便利です。
<?php
function add(int $a, int $b, int $c): int
{
return $a + $b + $c;
}
$args = [1, 2, 3];
// 従来の書き方
echo call_user_func_array('add', $args); // 6
// スプレッド演算子を使った書き方
echo add(...$args); // 6
call_user_func_array() を使わずに済むため、コードが読みやすくなります。
可変長引数(variadic)との組み合わせ
<?php
function sum(int ...$numbers): int
{
return array_sum($numbers);
}
$values = [10, 20, 30, 40];
echo sum(...$values); // 100
可変長引数を受け取る関数にも、そのままスプレッドで渡せます。
配列の先頭・末尾に要素を追加する
既存の配列の前後に要素を追加する際も、スプレッド演算子がシンプルです。
<?php
$fruits = ['banana', 'orange'];
// 先頭に追加
$withApple = ['apple', ...$fruits];
// ['apple', 'banana', 'orange']
// 末尾に追加
$withGrape = [...$fruits, 'grape'];
// ['banana', 'orange', 'grape']
// 両方
$full = ['apple', ...$fruits, 'grape'];
// ['apple', 'banana', 'orange', 'grape']
array_unshift() や array_push() を使わなくても、宣言的に書けるのが魅力です。
PHP 8.1:文字列キーの配列にも対応
PHP 8.1 以降では、文字列キーを持つ連想配列にもスプレッド演算子が使えます。
<?php
$defaults = [
'color' => 'red',
'size' => 'medium',
'stock' => true,
];
$override = [
'color' => 'blue',
'weight' => 1.5,
];
// 後から展開したものが優先される
$product = [...$defaults, ...$override];
print_r($product);
// Array
// (
// [color] => blue ← overrideで上書き
// [size] => medium
// [stock] => 1
// [weight] => 1.5 ← overrideで追加
// )
設定のデフォルト値と上書き値をマージするパターンによく使われます。
注意: PHP 8.0 以前では文字列キーのスプレッドはエラーになります。バージョンを確認しましょう。
array_merge との違い
array_merge() とスプレッド演算子の動作の違いを押さえておきましょう。
<?php
$a = ['x' => 1];
$b = ['x' => 2, 'y' => 3];
// array_merge: 文字列キーは後者で上書き
$r1 = array_merge($a, $b);
// ['x' => 2, 'y' => 3]
// スプレッド(PHP 8.1+): 同様に後者で上書き
$r2 = [...$a, ...$b];
// ['x' => 2, 'y' => 3]
数値キーの場合の挙動に違いがあります。
<?php
$c = [0 => 'a', 1 => 'b'];
$d = [0 => 'c', 1 => 'd'];
// array_merge: 数値キーは再採番される
$r3 = array_merge($c, $d);
// [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd']
// スプレッド: 数値キーも再採番される(同様)
$r4 = [...$c, ...$d];
// [0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd']
基本的な動作はほぼ同じですが、スプレッド演算子のほうが パフォーマンスがわずかに優れる ケースがあるとも言われています。可読性を重視してスプレッドを積極的に活用しましょう。
実践パターン:設定のマージ
実際のアプリケーションでよく見られる設定マージのパターンです。
<?php
function createDatabaseConfig(array $options = []): array
{
$defaults = [
'host' => 'localhost',
'port' => 3306,
'charset' => 'utf8mb4',
'timezone' => 'Asia/Tokyo',
];
return [...$defaults, ...$options];
}
$config = createDatabaseConfig([
'host' => 'db.example.com',
'port' => 5432,
]);
print_r($config);
// Array
// (
// [host] => db.example.com
// [port] => 5432
// [charset] => utf8mb4
// [timezone] => Asia/Tokyo
// )
デフォルト値を安全に保ちつつ、必要な部分だけ上書きできます。
まとめ
PHPのスプレッド演算子(...)を使った配列アンパックのポイントをまとめます。
| 用途 | 書き方 |
|---|---|
| 配列のマージ | [...$a, ...$b] |
| 先頭・末尾への追加 | ['new', ...$arr] |
| 関数への配列展開 | func(...$args) |
| 連想配列のマージ(PHP 8.1+) | [...$defaults, ...$override] |
スプレッド演算子を使うと、array_merge() や call_user_func_array() などの関数を使わずに直感的なコードが書けます。ぜひ日常のPHP開発に取り入れてみてください。