# ch05 — switch 文

Source: https://php-school.pages.dev/topics/conditional/ch05-switch/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: 条件分岐
Level: L2

Reference (official): https://www.php.net/manual/ja/language.control-structures.php

## 本文

# ch05 — switch 文

## 概要

ある変数の値によって 5 通り 10 通りと多くの分岐をしたい場面、`if / elseif / elseif / ...` をひたすら並べると縦に長くなって読みにくい。これを「**ある値を、各候補と等しいか順に照合する**」と意図を絞った形で書けるのが `switch` 文だ。曜日番号 1〜7 を曜日名に変換する、コマンド文字列でハンドラを振り分ける、ステータスコード別にメッセージを出す — こういう「1 つの値に対する多分岐」で読みやすさが大きく違う。

PHP の `switch` で **絶対に外せない約束** が、各 `case` の最後に `break` を書くこと。PHP は C 言語と同じく **フォールスルー仕様** で、`break` がないと一致した `case` から下の `case` の中身まで連続実行してしまう。これは意図的に複数 case で同じ処理を共有したい時に使えるが、**書き忘れによる連続実行は超頻出バグ** なので、毎回 `break` を書く癖を体に刷り込む。どの `case` にも当たらなかったときに通る `default` も合わせて覚えておく。

PHP 8 からは `switch` の代替として **`match` 式** が追加された。`match` は (1) 緩い比較 `==` ではなく **厳密比較 `===`** を使う、(2) `break` 不要 (フォールスルーしない)、(3) **式なので値を返せる** という違いがあり、ほとんどの場面で `match` の方が安全で読みやすい。とはいえ既存コードや古い PHP では `switch` が現役なので、まずは `switch` の挙動を正しく理解しておくのが本章の目的。

## 学習目標

- 値の多分岐を `switch` で書ける
- 各 `case` の最後に `break` が必要だと理解する
- どの値にも一致しなかった場合は `default` で受ける

## 所要時間

スライド 4 分 + ドリル 2 問 = **12 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | 数字 1-7 を曜日名に変換 |
| 02 | grade (A/B/C/D) を合格/不合格に振り分け |

## 採点

```bash
php scripts/grade.php topics/conditional/ch05-switch/drill/01-weekday/
```

## 関連チャプター

- [`ch02-if-else`](../ch02-if-else/) — `elseif` で書く多分岐との対比
- [`ch03-comparison`](../ch03-comparison/) — `switch` の照合は緩い比較 `==` で動く
- [`ch06-ternary`](../ch06-ternary/) — 2 分岐を 1 行で書く別形式

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 2 / Chapter 5
  目的: 値の多分岐を switch で書けるようにし、break 忘れによるフォールスルー事故を防ぐ
  扱わない: match 式 (PHP 8.0+) / 厳密比較版 switch
  読み上げ時間目安: 4 分
-->

# switch 文

Lesson 2 / Chapter 5

---

## if/elseif が長くなると読みにくい

```php
<?php
if ($n === 1) {
    echo "Mon\n";
} elseif ($n === 2) {
    echo "Tue\n";
} elseif ($n === 3) {
    echo "Wed\n";
} elseif ($n === 4) {
    echo "Thu\n";
}
```

「**1 つの値**」を「**たくさんの候補**」と比較する形は、
`switch` で書くと見通しが良くなる。

---

## `switch` の基本形

```php
<?php
switch ($n) {
    case 1:
        echo "Mon\n";
        break;
    case 2:
        echo "Tue\n";
        break;
    default:
        echo "unknown\n";
        break;
}
```

- `switch ($n)` で **判定したい値** を渡す
- `case 1:` は「$n が 1 のとき」
- `default:` は「どの case にも当たらないとき」

---

## `break` を忘れると **次の case まで流れる**

```php
<?php
switch ($n) {
    case 1:
        echo "Mon\n";
        // break を書き忘れた!
    case 2:
        echo "Tue\n";
        break;
}
```

`$n = 1` のとき、出力は:

```
Mon
Tue
```

- `break` がないと **次の case も実行される** (フォールスルー)
- これは **初学者の典型バグ**
- 各 `case` の最後には **必ず `break;`** を書く

---

## `default` で「それ以外」を受ける

```php
<?php
switch ($grade) {
    case "A":
        echo "Excellent\n";
        break;
    case "B":
        echo "Good\n";
        break;
    default:
        echo "Other\n";
        break;
}
```

- `default` は省略してもよい
- 省略するとどの case にも当たらない場合 **何も実行されない**
- 「想定外を検出したい」なら `default` を書く

---

## switch を使うべきかどうか

| 判定したいこと | 推奨 |
|---|---|
| 1 つの値が「特定の候補のどれか」 | **switch** |
| 範囲チェック (`$n >= 0 && $n <= 100`) | **if** |
| 複雑な複合条件 (`$a > 0 && $b < 10`) | **if** |

`switch` は **「値の一致」専用** と覚える。

---

## このチャプターでできるようになること

✅ `switch` で値の多分岐を書ける
✅ 各 case の最後に `break` を付けられる
✅ `default` で「それ以外」を受けられる
✅ `break` 忘れによるフォールスルー事故を防げる

→ ドリルへ
