PHP 8.0で導入されたmatch式は、従来のswitch文をより洗練させ、安全にした制御構造です。
これまで条件分岐には主にif文やswitch文が利用されてきましたが、match式の登場によりソースコードの可読性は飛躍的に向上しました。
特にモダンなPHP開発においては、「値を返す式」としての性質を持つmatch式を使いこなすことが必須のスキルと言えます。
本記事では、match式の基本的な書き方から、従来のswitch文との決定的な違い、そして実務で役立つ具体的な活用パターンまで詳しく紹介します。
match式とは?基本構文と特徴
match式は、指定された入力値に基づいて複数の選択肢から一つの結果を導き出すための構文です。
最大の特徴は、単なる制御フローではなく「式(Expression)」であるため、その評価結果をそのまま変数に代入できる点にあります。
match式の基本構文
match式の基本的な書き方は以下の通りです。
$status = 200;
$message = match ($status) {
200 => '成功です',
404 => 'ページが見つかりません',
500 => 'サーバーエラーが発生しました',
default => '不明なステータスです',
};
echo $message;
成功です
上記のコードでは、$statusの値に応じて対応する文字列が返され、変数$messageに直接格納されています。
各条件の末尾にはカンマ(,)が必要であり、switch文のようなcaseキーワードやbreak文は一切必要ありません。
match式が持つ主なメリット
match式を採用することで、エンジニアは以下のようなメリットを享受できます。
- コードが短くなり、記述ミス(タイポ)を減らせる。
- 厳密な型比較(===)が行われるため、予期せぬバグを防げる。
- 戻り値があるため、変数の初期化忘れを防ぎやすい。
- 網羅性がチェックされるため、未定義のパターンがあればエラーとして即座に検知できる。
match式とswitch文の決定的な違い
match式はしばしば「switch文の進化系」と呼ばれますが、その動作原理には重要な違いがいくつか存在します。
これらの違いを正しく理解していないと、既存のコードをmatch式に置き換えた際に意図しない動作を引き起こす可能性があります。
1. 厳密な比較(===)か、緩やかな比較(==)か
switch文は「緩やかな比較(==)」を使用して値を判定します。
そのため、数値の0と空文字列''が同一視されてしまうといった問題がありました。
対してmatch式は、常に「厳密な比較(===)」を行います。
型まで含めて一致している必要があるため、より堅牢なプログラムを作成することが可能です。
2. 戻り値の有無
switch文は「文(Statement)」であり、それ自体が値を持ちません。
そのため、switch文の中で変数に値を代入する作業を繰り返す必要がありました。
一方、match式は「式(Expression)」であるため、評価された結果を直接返すことができます。
3. 網羅性のチェックと例外
match式では、渡された値がいずれの条件にも合致せず、かつdefaultキーワードが定義されていない場合、UnhandledMatchErrorという致命的なエラーが発生します。
switch文では何にも合致しない場合に単に無視されるだけでしたが、match式は「すべてのパターンを考慮すること」を開発者に強制します。
比較表:match vs switch
| 機能 | match式 | switch文 |
|---|---|---|
| 比較方法 | 厳密な比較(===) | 緩やかな比較(==) |
| 戻り値 | あり(式として評価される) | なし(文である) |
| フォールスルー | なし(自動的に終了する) | あり(breakが必要) |
| 未合致時の挙動 | UnhandledMatchErrorをスロー | 何もしない |
match式の実用的な書き方パターン
ここからは、実務で頻繁に利用されるmatch式の具体的な活用シーンを見ていきましょう。
複数の条件を一つの結果にまとめる
複数の値に対して同じ結果を返したい場合、カンマで区切って記述するだけで簡単にグループ化できます。
$extension = 'jpg';
$fileType = match ($extension) {
'jpg', 'jpeg', 'png', 'gif' => '画像ファイル',
'mp4', 'avi', 'mov' => '動画ファイル',
'pdf' => 'ドキュメント',
default => '不明な形式',
};
echo $fileType;
画像ファイル
switch文のようにcase 'jpg': case 'jpeg': ...と縦に並べる必要がないため、非常にスッキリとした見た目になります。
条件式として比較演算子を利用する(trueパターンの活用)
match式の引数にtrueを渡すことで、各アーム(条件行)に複雑な比較式を記述することができます。
これは、数値の範囲指定などで非常に役立ちます。
$age = 25;
$category = match (true) {
$age < 13 => '子供',
$age < 20 => 'ティーンエイジャー',
$age < 65 => '成人',
default => 'シニア',
};
echo $category;
成人
この手法は「特定の値を比較するのではなく、条件式の結果がtrueになるものを探す」というアプローチです。
if-elseif文の代わりとして、より宣言的な記述が可能になります。
Enum(列挙型)との組み合わせ
PHP 8.1で導入されたEnum(列挙型)とmatch式は、相性が抜群です。
Enumの状態に基づいて処理を分岐させる際、match式を使うと安全かつ簡潔に記述できます。
enum Status {
case Pending;
case Active;
case Archived;
}
$currentStatus = Status::Active;
$label = match ($currentStatus) {
Status::Pending => '保留中',
Status::Active => '有効',
Status::Archived => 'アーカイブ済み',
};
echo $label;
有効
Enumのケースが追加された場合、match式にそのケースが不足しているとエラーが発生するため、修正漏れを防ぐ効果もあります。
match式を使用する際の注意点
非常に便利なmatch式ですが、いくつか注意すべきポイントがあります。
1. デフォルト値の設定を常に意識する
予期しない値が入ってくる可能性がある場合は、必ずdefaultアームを用意しましょう。
もしdefaultがない状態で一致する値がない場合、プログラムは停止してしまいます。
あえて例外を発生させて不具合を検知したい場合は省略しても構いませんが、基本的には定義しておくのが安全です。
2. 複雑なロジックをアーム内に書かない
match式のアーム(=>の右側)には一つの式しか書けません。
複数の処理を詰め込もうとして関数を無理やり連結させたりすると、可読性が著しく低下します。
複雑な処理が必要な場合は、別のメソッドに切り出し、そのメソッドを呼び出すように設計しましょう。
3. サイドエフェクト(副作用)の扱いに注意
match式は値を返すことに特化しています。
各条件の中でグローバル変数を書き換えたり、複雑な出力処理を行ったりするのは避けるべきです。
「入力に対して一意な出力を得る」という純粋な関数の考え方で利用するのがベストプラクティスです。
まとめ
PHP 8.xで導入されたmatch式は、従来のswitch文が抱えていた「比較の緩さ」や「記述の冗長性」を解消する優れた機能です。
「厳密な比較」「式としての評価」「網羅性の確保」という強力な特徴により、私たちの書くコードをより安全で、読みやすいものに変えてくれます。
もし現在、switch文や複雑なif文の連続でコードが煩雑になっている箇所があれば、ぜひmatch式への書き換えを検討してみてください。
モダンなPHPの書き方を取り入れることで、保守性の高い高品質なアプリケーション開発が可能になるでしょう。
