# ch02 — throw で例外を投げる

Source: https://php-school.pages.dev/topics/exception/ch02-throw/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: 例外処理
Level: L3

Reference (official): https://www.php.net/manual/ja/language.exceptions.php

## 本文

# ch02 — throw で例外を投げる

## 概要

ch01 では `try / catch` で「**飛んできた例外を受け止める**」側を扱った。この章では反対側、つまり「**自分から例外を投げる**」側を学ぶ。書き方は `throw new Exception("メッセージ")` の 1 行で、これを実行した瞬間にその関数の処理は中断され、呼び出し元の `catch` まで一気に巻き戻る。

例外の最大の効用は、**関数の戻り値を「正常な結果のみ」に絞れる** ことだ。たとえば年齢を返す関数が `-1` を「エラー」のサインとして返していると、呼び出し側は毎回 `-1` チェックを挟むことになる。代わりに「不正なら throw、正常なら数値を return」と決めておけば、戻り値は常に意味のある年齢になり、エラー処理は `catch` 側に分離できる。

どこで投げ、どこで捕まえるかは設計判断。一般的には **「異常を最初に検知した場所で throw」「対応できるレイヤーで catch」** が定石。たとえば DB アクセス層が SQL エラーを throw し、画面表示層が catch してユーザー向けメッセージに変換する、という形だ。この章のドリルでは「負の数なら throw」という最小例で、投げる側のコードに慣れる。

## 学習目標

- `throw new Exception("...")` で自分から例外を発生させられる
- 「想定外の入力」を検知したら、エラーを呼び出し元に伝えられる
- 単に `echo "エラー"` するのと違って、処理の流れを **強制的に中断** できる

## 所要時間

スライド 4 分 + ドリル 1 問 = **10 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | 入力が負なら throw、正なら普通に出力する |

## スライド

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

<!--
LLM_CONTEXT:
  Lesson 10 / Chapter 2
  目的: throw new Exception("...") で自分から例外を発生させる
  扱わない: getMessage (ch03) / 複数 catch (ch04) / カスタム例外 (ch06)
  読み上げ時間目安: 3 分半〜4 分
-->

# throw で例外を投げる

Lesson 10 / Chapter 2

---

## 「想定外の入力」を検知したい

```php
<?php
function square(int $n): int {
    if ($n < 0) {
        // 負の数は想定外…どう伝える?
        echo "エラー: 負の数\n";
        return 0;
    }
    return $n * $n;
}
```

- `echo` だけだと、呼び出し元はエラーに気付けない
- `return 0` も「正常な 0」と区別がつかない
- 「失敗した」と確実に伝える仕組みが欲しい

---

## `throw new Exception("...")` で例外を投げる

```php
<?php
function square(int $n): int {
    if ($n < 0) {
        throw new Exception("負の数は計算できません");
    }
    return $n * $n;
}
```

- `throw` で例外を **投げる**
- `new Exception("メッセージ")` で例外オブジェクトを作る
- 投げた瞬間、その関数はそこで停止する

---

## 投げた例外は呼び出し元に伝わる

```php
<?php
try {
    echo square(-5) . "\n";
} catch (Exception $e) {
    echo "失敗しました\n";
}
```

実行結果:

```
失敗しました
```

- `square(-5)` で `throw` → 関数を抜ける
- 呼び出し元の `try / catch` で受け止められる

---

## 正常時はそのまま動く

```php
<?php
try {
    echo square(4) . "\n";   // 16
} catch (Exception $e) {
    echo "失敗\n";
}
```

実行結果:

```
16
```

- 例外を投げなければ `catch` ブロックには来ない
- 「異常時だけ throw、正常時は普通に return」が基本パターン

---

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

✅ `throw new Exception("...")` で例外を投げられる
✅ 投げると関数はその場で停止する
✅ 呼び出し元の try / catch で受け止められる
✅ 「異常 → throw、正常 → return」を書き分けられる

→ ドリルへ
