match式で該当する条件が無いと UnhandledMatchError になる
match式は該当するcaseが1つも無いと、switch文のように黙って何もしないのではなく、UnhandledMatchErrorという例外を投げます。想定していない値が来た場合の安全装置として働きます。
エラーメッセージの読み方
Fatal error: Uncaught UnhandledMatchError: Unhandled match case 'F' in main.php:3
main.php- ファイル名
3- 行番号 — 実際にクラッシュした行
UnhandledMatchError- 例外クラス — 何が起きたか。ここを検索するのが最短です
Unhandled match case 'F'- 内容 — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 <?php 2 $grade = "F"; ^ 3 $point = match ($grade) { 4 "A" => 4, 5 "B" => 3, 6 }; 7 echo $point;
match式はswitchと違い、該当するcaseが無いと黙って通り抜けません。UnhandledMatchErrorを投げてプログラムを止めます。
直し方: "F" を "A" にします。
パターン2
1 <?php 2 $status = 3 ; ^ 3 $label = match ($status) { 4 1 => "active", 5 2 => "inactive", 6 }; 7 echo $label;
matchに該当するcaseが無いとUnhandledMatchErrorになります。想定外の値をそのまま渡さないよう、事前の検証かdefault相当のcaseが必要です。
直し方: 3 を 1 にします。
パターン3
1 <?php 2 $size = "L" ; ^ 3 $px = match ($size) { 4 "S" => 12, 5 "M" => 16, 6 }; 7 echo $px;
sizeに"L"のような未定義のケースを渡すとUnhandledMatchErrorになります。matchはswitchのフォールスルーのような黙って無視する挙動をしません。
直し方: "L" を "M" にします。
パターン4
1 <?php 2 $level = 3 ; ^ 3 $desc = match ($level) { 4 1 => "low", 5 2 => "mid", 6 }; 7 echo $desc;
matchに該当するcaseが無いとUnhandledMatchErrorになります。
直し方: 3 を 1 にします。
パターン5
1 <?php 2 $code = "ERR"; ^ 3 $msg = match ($code) { 4 "OK" => "good", 5 "NG" => "bad", 6 }; 7 echo $msg;
codeに"ERR"のような未定義のケースを渡すとUnhandledMatchErrorになります。
直し方: "ERR" を "OK" にします。
よくある誤解
「matchもswitchと同じで、該当が無ければ何もせず通り抜けるはず」という思い込みは誤りです。matchは該当なしを許さない設計で、defaultに相当するものが無ければ必ず例外になります。
実務での勘所
matchはPHP 8.0で、switchの2つの弱点を同時に解消するために新設された構文です。switchは==による緩い比較を行うため型の異なる値同士がたまたま一致してしまうことがありますが、matchは===と同じ厳密な比較を行います。加えて、switchは該当が無ければ黙って何もしませんが、matchは該当なしを異常事態とみなして例外を投げます。「緩い比較」と「該当なしの見逃し」という、switch文の代表的な2つの落とし穴を踏まえて設計された、より安全な代替構文です。