# ch08 — 入力検証で例外を活用する

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

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

## 本文

# ch08 — 入力検証で例外を活用する

## 概要

トピックの締めとして、例外を **入力検証 (バリデーション)** に応用する実用パターンを扱う。フォーム入力・API パラメータ・関数引数――どんな入り口でも、「想定外の値はその場で弾く」ことで、後段のロジックを「もう変な値は来ない」前提で書ける。

具体的な書き方は **ガード節 (guard clause)** と呼ばれるスタイル。関数の冒頭で `if ($age < 0 || $age > 150) { throw new InvalidArgumentException(...); }` のように、不正値を **早期 throw** で振り落とす。残りの処理は正常値だけが流れてくる前提になるので、ネストが減り、本来のロジックが読みやすくなる。

PHP では値の不正には **`InvalidArgumentException`** を投げる慣習がある (標準ライブラリも同様)。大きなアプリでは Symfony Validator / Laravel Validator などへ発展する。この章は「年齢 0-150」という最小例で、ガード節と例外の組み合わせを身体に通す。

## 学習目標

- 入力値のチェックで例外を投げる「検証パターン」を書ける
- 範囲外なら `InvalidArgumentException` を投げる慣習を知っている
- 呼び出し元は `try / catch` だけで OK / NG の分岐ができる

## 所要時間

スライド 5 分 + ドリル 1 問 = **12 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | 年齢が 0-150 の範囲外なら例外を投げる |

## スライド

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

<!--
LLM_CONTEXT:
  Lesson 10 / Chapter 8
  目的: 入力値検証 (validation) を例外で表現する典型パターンを身につける
  扱わない: フォームバリデーション全般 / 複数フィールド検証 / 例外を集めて一括で出す手法
  読み上げ時間目安: 4 分半〜5 分
-->

# 入力検証で例外を活用する

Lesson 10 / Chapter 8

---

## 「ありえない値」が来たらどうする?

```php
<?php
function registerAge(int $age) {
    if ($age < 0 || $age > 150) {
        // どうやって呼び出し元に伝える?
        return false;
    }
    // 登録処理
    return true;
}
```

- `return false` だと「失敗した理由」が伝わらない
- if/else の戻り値チェックが連鎖して読みにくい

---

## 例外で「ありえない入力」を表現する

```php
<?php
function registerAge(int $age) {
    if ($age < 0 || $age > 150) {
        throw new InvalidArgumentException(
            "age は 0-150 の範囲: $age"
        );
    }
    // 登録処理
    echo "登録: age = $age\n";
}
```

- `InvalidArgumentException` は「引数が不正」を表す標準例外
- メッセージに値を含めると、原因がすぐ分かる

---

## 呼び出し側は `try / catch` でまとめて受ける

```php
<?php
try {
    registerAge($age);
    echo "OK\n";
} catch (InvalidArgumentException $e) {
    echo "NG: " . $e->getMessage() . "\n";
}
```

- 1 つの catch で全部の検証エラーを拾える
- 「正常ルート」と「失敗ルート」が綺麗に分かれる

---

## ガード節パターン

```php
<?php
function registerAge(int $age) {
    if ($age < 0)   throw new InvalidArgumentException("負の値");
    if ($age > 150) throw new InvalidArgumentException("大きすぎる");
    if (!is_int($age)) throw new InvalidArgumentException("整数でない");

    // ここまで来たら全部 OK
    // 本来の処理を書く
}
```

- 「ありえない条件」を最初にチェックして throw
- 関数の本体は **正常ケースだけ** を書けばよい
- ネストが浅くなり、読みやすくなる

---

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

✅ 入力検証で例外を投げる典型パターンを書ける
✅ `InvalidArgumentException` の慣習を知っている
✅ ガード節で読みやすくできる
✅ try / catch 1 つで OK / NG を分岐できる

→ ドリルへ
