PHP7.4から、配列でアンパックが使えるようになりました。アンパックとは一般的にスプレッド演算子・スプレッド構文と呼ばれるもの。
'...' のやつです。
これで、配列の定義だけでarray_merge()と同じ結果が出せます。JavaScriptにはすでにある機能。
この機能は言葉で説明するよりも百聞は一見にしかず。サンプルコードで見てみましょう。
$org = [1, 2, 3];
$new = [4, 5, 6];
$func = array_merge( $org, $new );
$unpack = [...$org, ...$new];
var_dump($func);
var_dump($unpack);
array(6) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
}
array(6) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
[5]=>
int(6)
}
array_merge() と同じことを配列の定義だけでできます。連想配列もできます。
$org = [1 => 'first', 2 => 'second', 3 => 'third'];
$new = [4 => 'fourth', 5 => 'fifth', 6 => 'sixth'];
$func = array_merge( $org, $new );
$unpack = [...$org, ...$new];
var_dump($func);
var_dump($unpack);
array(6) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
[3]=>
string(6) "fourth"
[4]=>
string(5) "fifth"
[5]=>
string(5) "sixth"
}
array(6) {
[0]=>
string(5) "first"
[1]=>
string(6) "second"
[2]=>
string(5) "third"
[3]=>
string(6) "fourth"
[4]=>
string(5) "fifth"
[5]=>
string(5) "sixth"
}
ただし、要素のキーは0から始まる数値に変換されます。キーは消えてしまう。でもこれは array_merge() も同じ。
今度は数字(文字列)でやってみましょう。
$org = ['1' => '1st', '2' => '2nd', '3' => '3rd'];
$new = ['4' => '4th', '5' => '5th', '6' => '6th'];
$func = array_merge( $org, $new );
$unpack = [...$org, ...$new];
var_dump($func);
var_dump($unpack);
array(6) {
[0]=>
string(3) "1st"
[1]=>
string(3) "2nd"
[2]=>
string(3) "3rd"
[3]=>
string(3) "4th"
[4]=>
string(3) "5th"
[5]=>
string(3) "6th"
}
array(6) {
[0]=>
string(3) "1st"
[1]=>
string(3) "2nd"
[2]=>
string(3) "3rd"
[3]=>
string(3) "4th"
[4]=>
string(3) "5th"
[5]=>
string(3) "6th"
}
どうやら数字はキャストされてint型になるようです。結果は0から始まる数値のキー。もちろんarray_merge()も同じ。
最後に、文字列のキーでやってみます。
$org = ['a' => '1st', 'b' => '2nd', 'c' => '3rd'];
$new = ['d' => '4th', 'e' => '5th', 'f' => '6th'];
$func = array_merge( $org, $new );
$unpack = [...$org, ...$new];
var_dump($func);
var_dump($unpack);
PHP Fatal error: Uncaught Error: Cannot unpack array with string keys in /home/vagrant/php-test.php:7
Stack trace:
#0 {main}
thrown in /home/vagrant/php-test.php on line 7
アンパックは文字列のキーは使えません。ちなみに、array_merge() の結果はこうなります。
array(6) {
["a"]=>
string(3) "1st"
["b"]=>
string(3) "2nd"
["c"]=>
string(3) "3rd"
["d"]=>
string(3) "4th"
["e"]=>
string(3) "5th"
["f"]=>
string(3) "6th"
}
array_merge() では、文字列のキーが被ったときは、あとから追加されたもので上書きされます。
$org = ['a' => '1st', 'b' => '2nd', 'c' => '3rd'];
$new = ['c' => '4th', 'd' => '5th', 'e' => '6th'];
$func = array_merge( $org, $new );
var_dump($func);
array(5) {
["a"]=>
string(3) "1st"
["b"]=>
string(3) "2nd"
["c"]=>
string(3) "4th"
["d"]=>
string(3) "5th"
["e"]=>
string(3) "6th"
}
マージ(merge)ってそういうものですからね? 変更点のあるものだけを変えるのがマージだから。
array_merge() と アンパック、どっちを使うべき?
ここで、array_merge() とアンパックのどっちを使えば良いんだ? ということになるんですが、ただの配列ならアンパックのほうがいいです。
アンパックは言語の構文であるのに対しarray_merge()は関数なので、関数の処理の分だけ時間がかかります。
しかし、構文内でも配列のマージ処理が入ってるので膨大なサイズでないかぎりその差はほとんどないでしょう。
アンパックのほうが見た目は分かりやすいです。配列を足してる感が一目瞭然なので。
じつはarray_merge()の内部は変更されて、ただの配列だったらアンパックを使ってる可能性もあるんじゃないか?
連想配列の場合はarray_merge() でしょう。さすがに致命的なPHPエラーが発生する可能性のある処理は実装してはいけません。
PHP8.1から、アンパックは文字列のキーにも対応しました。
これでarray_merge()と同じことがアンパックでもできます。
PHP公式ドキュメント