はじめに
昔こんな記事を書いたことがあります。
switch文撲滅委員会
switch文には罠が多く極力使わない方が良い、ということを言いたくて書いたものです。
この度PHP8からmatch式
が使えるようになりました。
switch文を撲滅してmatch式を推奨していきたいのでこの記事を書きました。
match式とは
公式ドキュメント
switch文と比較すると以下の違い(利点)があります。
switch | match | |
---|---|---|
比較 | 曖昧 | 厳密 |
break | 必要 | 不要 |
例外値 | スルー | 例外 |
サンプルコード
比較
前回の記事で出したサンプルコード
sample1_switch.php
<?php$sample=1;switch($sample){casetrue:echo'これはtrueです'."\n";break;case1:echo'これは数値の1です'."\n";break;default:echo'これは1ではありません'."\n";break;}// 結果// これはtrueです
このコードでは曖昧比較であるためcase trueの部分に入ってしまうのが課題でした。
ではmatch式で書くとどうなるでしょうか?
sample1_match.php
<?php$sample=1;$return_value=match($sample){true=>'これはtrueです',1=>'これは数値の1です',default=>'これは1ではありません',};var_dump($return_value);// 結果// string(25) "これは数値の1です"
自動で厳密比較をしてくれました。
フォールスルー
sample2_switch.php
<?php$sample='a';switch($sample){case'a':echo'これはaです'."\n";case'b':echo'これはbです'."\n";case'c':echo'これはcです'."\n";default:echo'これはa,b,cではありません'."\n";}// 結果// これはaです// これはbです// これはcです// これはa,b,cではありません
このコードではbreakを書いていないため全ての分岐が評価されるのが課題でした。
ではmatch式で書くとどうなるでしょうか?
sample2_match.php
<?php$sample='a';$return_value=match($sample){'a'=>'これはaです','b'=>'これはbです','c'=>'これはcです',default=>'これはa,b,cではありません',};var_dump($return_value);// 結果// string(16) "これはaです"
breakなしでもフォールスルーされませんでした。
例外値
sample3_switch.php
<?php$sample='d';switch($sample){case'a':echo'これはaです'."\n";case'b':echo'これはbです'."\n";case'c':echo'これはcです'."\n";}// 結果なし
defaultが未定義でどのケースにも合致しない場合、switch文ではスルーされていました(何も起きない)
ではmatch式で書くとどうなるでしょうか?
sample3_match.php
<?php$sample='d';$return_value=match($sample){'a'=>'これはaです','b'=>'これはbです','c'=>'これはcです',};var_dump($return_value);// 結果// PHP Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type string in sample3_match.php:3// Stack trace:// #0 {main}// thrown in sample3_match.php on line 3
どのケースにも合致しないとUnhandledMatchErrorの例外が投げられます。
これで意図しないケースにすぐに気付くことができ、より堅牢にコードを作成することが可能となりました。
まとめ
match式は今までのswitch文の罠だった部分をキレイに回避できるため、大変おすすめです。
PHP8を使っている方は是非match式で書いていきましょう!
付録
ローカルの環境をphp8にしたくなかったので挙動を試せるdocker環境を用意しました。
ご自由にお使いください。
https://github.com/yamamoto-hiroya/php8_practice