match式はswitchの上位互換なのか
match式はPHP 8で追加された分岐構文です。厳密比較・値を返す・網羅漏れで例外という特徴を持ち、switchの事故りやすい部分を避けられる書き方です。
PHP 8で入ったmatch式、switchの見た目違いくらいに思っている人が多い気がします。実際は挙動がいくつか違っていて、switchのハマりどころを回避できるようになっています。
厳密比較である
switchは緩やかな比較(==)ですが、matchは厳密比較(===)です。これが地味に効きます。
$x = '1';
switch ($x) {
case 1: echo 'switchは数値1にマッチ'; break; // これが実行される
}
echo match($x) {
1 => '数値1',
'1' => '文字列1', // matchはこっち
};
switchの緩い比較で「文字列なのに数値のcaseに入ってしまう」バグ、経験ある人も多いはず。matchはそれが起きません。
breakいらず・値を返す
matchは式なので値を返します。breakの書き忘れによるフォールスルー事故がそもそも発生しません。
$label = match($status) {
'draft' => '下書き',
'publish', 'future' => '公開系',
default => '不明',
};
カンマ区切りで複数条件をまとめられます。
マッチしないと例外
defaultが無くてどれにもマッチしないと、matchはUnhandledMatchErrorを投げます。switchのように「何も起きず素通り」しないので、想定外の値に気づけます。これは安全側に倒れていて良い挙動です。
まとめ
厳密比較・break不要・網羅漏れで例外。この3点で、matchはswitchの事故りやすい部分を潰しています。値を返す分岐ならmatchが基本、複数文を実行したいならswitch、という住み分けでいいと思います。
よくある質問
Q. matchでdefaultを書かないとどうなりますか。
A. どのケースにもマッチしないとUnhandledMatchErrorが投げられます。switchのように素通りしないので、想定外の値に気づけます。
Q. matchとswitchはどう使い分ければいいですか。
A. 値を返す分岐ならmatch、複数の文を実行したい処理ならswitch、という住み分けが素直だと思います。