はじめに
昔こんな記事を書いたことがあります。
switch文撲滅委員会
switch文には罠が多く極力使わない方が良い、ということを言いたくて書いたものです。
この度PHP8からmatch式
が使えるようになりました。
switch文を撲滅してmatch式を推奨していきたいのでこの記事を書きました。
match式とは
公式ドキュメント
switch文と比較すると以下の違い(利点)があります。
switch | match | |
---|---|---|
比較 | 曖昧 | 厳密 |
break | 必要 | 不要 |
例外値 | スルー | 例外 |
サンプルコード
比較
前回の記事で出したサンプルコード
<?php
$sample = 1;
switch($sample){
case true:
echo 'これはtrueです'."\n";
break;
case 1:
echo 'これは数値の1です'."\n";
break;
default:
echo 'これは1ではありません'."\n";
break;
}
// 結果
// これはtrueです
このコードでは曖昧比較であるためcase trueの部分に入ってしまうのが課題でした。
ではmatch式で書くとどうなるでしょうか?
<?php
$sample = 1;
$return_value = match ($sample) {
true => 'これはtrueです',
1 => 'これは数値の1です',
default => 'これは1ではありません',
};
var_dump($return_value);
// 結果
// string(25) "これは数値の1です"
自動で厳密比較をしてくれました。
フォールスルー
<?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式で書くとどうなるでしょうか?
<?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なしでもフォールスルーされませんでした。
例外値
<?php
$sample = 'd';
switch($sample){
case 'a':
echo 'これはaです'."\n";
case 'b':
echo 'これはbです'."\n";
case 'c':
echo 'これはcです'."\n";
}
// 結果なし
defaultが未定義でどのケースにも合致しない場合、switch文ではスルーされていました(何も起きない)
ではmatch式で書くとどうなるでしょうか?
<?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