match式とは
PHP8.0で導入されたmatch式は、switch文の進化版とも言える制御構文です。見た目は似ていますが、いくつかの重要な違いがあります。
<?php
$status = 2;
$label = match($status) {
1 => '下書き',
2 => '公開中',
3 => '非公開',
default => '不明',
};
echo $label; // 公開中
matchは式であるため、値を返します。結果を変数に代入したり、そのまま関数の引数として渡したりできます。
switch文とmatch式の違い
1. 厳密比較(===)を使う
switch文は==(緩やかな比較)を使いますが、match式は===(厳密な比較)を使います。
<?php
$value = '1'; // 文字列の '1'
// switch では true になってしまう
switch ($value) {
case 1:
echo 'switch: 一致した'; // ← これが実行される(危険!)
break;
}
// match では型も含めて比較するので一致しない
$result = match($value) {
1 => 'int の 1',
'1' => '文字列の 1', // ← こちらが一致する
default => '一致なし',
};
echo $result; // 文字列の 1
この挙動の違いは、思わぬバグを防ぐうえで非常に重要です。
2. breakが不要
switchでは各caseにbreakを書き忘れると、次のcaseに処理がフォールスルーしてしまいます。match式ではフォールスルーはなく、breakも必要ありません。
3. defaultがない場合に例外を投げる
switchではdefaultがない場合、何も処理されずに終わります。一方match式は、どのアームにも一致しなかった場合に\UnhandledMatchErrorが投げられます。
<?php
$code = 99;
try {
$message = match($code) {
200 => 'OK',
404 => 'Not Found',
500 => 'Internal Server Error',
};
} catch (\UnhandledMatchError $e) {
echo '対応していないコードです: ' . $code;
// 対応していないコードです: 99
}
これにより、考慮漏れのケースを明示的にハンドリングできます。
実践的な活用パターン
複数の値を1つのアームにまとめる
カンマ区切りで複数の値を同じアームに割り当てられます。
<?php
$day = 'Saturday';
$type = match($day) {
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday' => '平日',
'Saturday', 'Sunday' => '休日',
default => '不明',
};
echo $type; // 休日
条件式と組み合わせる(no-match with true)
match(true)を使うと、条件式をアームとして記述できます。
<?php
$score = 75;
$grade = match(true) {
$score >= 90 => 'S',
$score >= 80 => 'A',
$score >= 70 => 'B',
$score >= 60 => 'C',
default => 'D',
};
echo $grade; // B
if-elseifのチェーンをすっきりと書き直せるパターンです。
Enumとの組み合わせ(PHP8.1以降)
PHP8.1で導入されたEnumと組み合わせると、より型安全なコードが書けます。
<?php
enum Color
{
case Red;
case Green;
case Blue;
}
$color = Color::Green;
$hex = match($color) {
Color::Red => '#FF0000',
Color::Green => '#00FF00',
Color::Blue => '#0000FF',
};
echo $hex; // #00FF00
Enumのすべてのケースを網羅していればdefaultが不要になり、将来ケースが追加されたときにUnhandledMatchErrorで気づくことができます。
関数の戻り値として直接使う
matchは式なので、returnと組み合わせてメソッド内で直接返すことができます。
<?php
function getHttpMessage(int $code): string
{
return match($code) {
200 => 'OK',
201 => 'Created',
400 => 'Bad Request',
401 => 'Unauthorized',
403 => 'Forbidden',
404 => 'Not Found',
500 => 'Internal Server Error',
default => 'Unknown Status',
};
}
echo getHttpMessage(403); // Forbidden
match式を使うべき場面のまとめ
| 状況 | 推奨 |
|---|---|
| 値を返したい | match式 |
| 型の厳密な比較が必要 | match式 |
| 考慮漏れを例外で検知したい | match式 |
| 複雑な処理ブロックが必要 | switch文 |
| PHP7以前との互換性が必要 | switch文 |
まとめ
match式はswitch文に比べて、厳密な比較・フォールスルーなし・式として使えるという3つの大きな利点があります。PHP8以降のコードでは積極的にmatch式を採用することで、より安全で読みやすいコードを書くことができます。
Enumとの組み合わせやmatch(true)パターンも覚えておくと、実務でのコードがぐっとすっきりします。ぜひ日々の開発に取り入れてみてください。