【PHP】switch文の使い方|break・フォールスルー・緩い比較とmatch式

PHPの switch 文は、1つの値を複数の候補と比べて分岐する制御構造です。if-elseif を並べるより条件の見通しがよくなりますが、break忘れ緩い比較(==)の落とし穴には注意が必要です。この記事では基本から、PHP 8の match 式まで解説します。

この記事の結論:case の最後には break を付けます(忘れると次のcaseまで実行されます)。switchは緩い比較(==で判定する点に注意。厳格に判定したい・値を返したいならPHP 8の matchが便利です。
スポンサーリンク

switch文の基本構造

基本構文
<?php
switch ($変数や式) {
    case 値1:
        // 値1に一致したときの処理
        break;
    case 値2:
        // 値2に一致したときの処理
        break;
    default:
        // どれにも一致しないときの処理
}

実例:曜日の判定

曜日を判定する
<?php
$day = "Wed";

switch ($day) {
    case "Mon":
        echo "今日は月曜日です。";
        break;
    case "Tue":
        echo "今日は火曜日です。";
        break;
    case "Wed":
        echo "今日は水曜日です。"; // ← これが実行される
        break;
    default:
        echo "それ以外の曜日です。";
}

break忘れとフォールスルー

最も多いミスが break の付け忘れです。break が無いと、一致したcase以降の処理が条件に関係なく次々に実行されます(フォールスルー)

NG: breakを忘れると次も実行される
<?php
$n = 1;
switch ($n) {
    case 1:
        echo "1";
        // break が無い!
    case 2:
        echo "2"; // ← 1なのに実行される
        break;
}
// 出力: 12

逆に、この性質を意図的に使って複数のcaseで同じ処理を行うこともできます。空のcaseを並べると「OR条件」のように書けます。

OK: 意図的なフォールスルー(複数caseで共通処理)
<?php
$day = "Sat";
switch ($day) {
    case "Sat":
    case "Sun":
        echo "週末です"; // Sat と Sun で共通
        break;
    default:
        echo "平日です";
}

注意:switchは「緩い比較(==)」で判定する

見落としがちですが、switch の一致判定は厳格比較(===)ではなく緩い比較(==です。そのため、型が違っても値が一致すればマッチしてしまいます。

緩い比較の例
<?php
$v = "1"; // 文字列の "1"
switch ($v) {
    case 1:  // 数値の 1
        echo "数値1にマッチした"; // ← マッチする("1" == 1)
        break;
    default:
        echo "マッチしない";
}
型まで含めて厳密に判定したい場合、switchは不向きです。なおPHP 8.0で文字列と数値の比較ルールが変わり0 == "foo" は(PHP 7では true でしたが)false になりました。型を区別したい場合は、後述の match 式を使うのが安全です。

PHP 8のmatch式(厳格・値を返す)

PHP 8.0以降では match 式が使えます。switchとの主な違いは、厳格比較(===であること、値を返すこと、break不要(フォールスルーしない)ことです。

match式(PHP 8.0+)
<?php
$day = "Sat";

$result = match ($day) {
    "Mon", "Tue", "Wed", "Thu", "Fri" => "平日",
    "Sat", "Sun" => "週末",
    default => "不明",
};

echo $result; // 週末
match は厳格比較なので "1"1 は別扱いです。値を変数に代入したい・型を区別したい場合は match、各caseで複数行の処理をしたい場合は switch、と使い分けると良いでしょう。条件分岐全般はif文による条件分岐も参照してください。

よくある質問(FAQ)

Qbreakを忘れるとどうなりますか?
A一致したcase以降の処理が、条件に関係なく次々に実行されます(フォールスルー)。各caseの最後に break を付けて防ぎます。複数caseで同じ処理をしたいときは、あえて空のcaseを並べて意図的にフォールスルーさせます。
Qswitchは型まで厳密に比較しますか?
Aいいえ。緩い比較(==です。"1"1 は一致扱いになります。型を区別したいなら、厳格比較(===)の matchを使ってください。
Qswitchとmatchはどう使い分けますか?
A値を返したい・型を厳密に判定したいなら match(PHP 8.0+)、各分岐で複数行の処理をしたいなら switch が向いています。matchはbreak不要でフォールスルーしません。
Qdefaultはどこに書きますか?
A慣例として最後に書きますが、位置は任意です。どのcaseにも一致しなかったときに実行されます。書き忘れると、一致しない場合に何も実行されません。

まとめ

PHPのswitch文のポイントを整理します。

  • 各caseの最後に break(忘れるとフォールスルー)
  • 複数caseで共通処理は意図的なフォールスルーで書ける
  • switchは緩い比較(==。型は区別しない
  • 厳格に判定・値を返すならPHP 8の match
  • PHP 8で文字列と数値の比較ルールが変わった点にも注意

関連として、if文による条件分岐strcmpで文字列を比較する方法ループ処理を行う方法もあわせて読むと、PHPの制御構造に強くなれます。