PHP8リリースから4年が経ち、社内プロジェクトもPHP8へ移行されてしばらく経った。PHP8化した恩恵を受けるため、是非紹介したい新機能として match
式がある。
switch
文のあまりイケてなかったところを改善したような機能であり、可読性の悪かった switch
や if/else
のネストで書かれた処理をより簡潔かつわかりやすく書ける可能性がある。
<?php
$food = 'cake';
$return_value = match ($food) {
'apple' => 'This food is an apple',
'bar' => 'This food is a bar',
'cake' => 'This food is a cake',
};
var_dump($return_value); // 出力 => string(19) "This food is a cake"
?>
<?php
$age = 18;
$output = match (true) {
$age < 2 => "Baby",
$age < 13 => "Child",
$age <= 19 => "Teenager",
$age > 19 => "Young adult",
$age >= 40 => "Old adult"
};
var_dump($output); //出力 => string(8) "Teenager"
?>
詳しい機能の仕様、使用例に関してはPHP公式ドキュメントを見るのが一番よい。まず目を通そう。
この記事で言いたかったことはこれで全てだが、match
が switch
の完全上位互換というわけではないため、補足情報として match
でできないことを挙げておく。
なお、記事のコードの一部はPHP公式ドキュメントから引用している。また、内容についても社内の周知を目的としているため他記事からの引用がメインであることに留意されたし(引用元は記事最後に記載)。
match
にできないこと( switch
と比較して)
複数行の実行
match
は条件式に対して返却式をひとつしか取れないため、複数行の処理を実行することはできない。 function
にまとめて呼び出すなどの方法を取る必要がある。
switch ($value) { //こういうのはmatchではできない
case 'abc':
doA();
doB();
doC();
break;
case 'xyz':
doX();
doY();
doZ();
break;
}
条件によって一部だけ実行
switch
ではbreakしないかぎり下に書いた case
以降の処理も行われるため、あえてbreakしないことで条件によって処理の一部だけを実行したりしなかったりできる(可読性がよくないため推奨はしない)。
match
では条件式と一致した時点で返却式の値を返して処理を終了する。break;などが必要ないため、多くの場合 match
の方が簡潔だ。
switch ($value) { //こういうのはmatchではできない
case 'XYZ':
echo 'X';
// breakしない
case 'YZ':
echo 'Y';
// breakしない
case 'Z' :
echo 'Z';
break;
}
match
で対応できないケースを挙げはしたが、ほとんどの場面において switch
より match
を使った方がコードを見通してよく書けるだろう。条件分岐が必要な場面ではぜひ match
を選択肢に入れよう。
参考資料
【PHP8】match 式のこれまでとこれから
match式が導入されるまでの経緯
現行と異なる仕様が記事中で紹介されているので混乱注意
switch文