ch06 8章中 6章目

ch06 — カスタム例外

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch06 — カスタム例外」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch06 — カスタム例外」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch06 — カスタム例外」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

throw new Exception("ユーザーが見つからない") のようにメッセージで判別する書き方は手軽だが、catch 側が getMessage() の文字列を見て分岐するハメになって脆い。文言が少し変わるだけで分岐が壊れるし、IDE の補完も効かない。

PHP では class UserNotFoundError extends Exception {} のように Exception を継承するだけ で、自分のドメインに合った例外クラスを作れる。中身を実装する必要は無く、空クラスでも十分意味がある。なぜなら catch は クラスの型で分岐 するので、catch (UserNotFoundError $e) と書いた瞬間に「これはユーザー未存在のときだけ来る」と読み手にも IDE にも伝わるからだ。

実用では「予約済みエラー」「在庫不足」「権限不足」のように、アプリの世界 (ドメイン) が持つ概念に対して 1 クラスずつ 例外を切るのが定石。標準の RuntimeException / LogicException のどちらを継承するかも設計上のヒントになる (実行時に外部要因で起きるなら Runtime、コードの論理ミスなら Logic)。この章のドリルは最小例で「クラスを作って投げて型で受ける」ループを通す。

学習目標

  • class MyError extends Exception {} で独自の例外クラスを作れる
  • 自作クラスを throw して、自作の型で catch できる
  • ドメイン固有のエラーを 型で区別 できるようになる

ドリル

no 内容
01 MyError extends Exception を作って投げて受ける

解説スライド 全 6 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. カスタム例外

    Lesson 10 / Chapter 6

  2. 標準の Exception だけだと区別がつかない

    <?php
    try {
        if (在庫不足) throw new Exception("在庫不足");
        if (支払い失敗) throw new Exception("支払い失敗");
    } catch (Exception $e) {
        // どっちの例外?
        // メッセージで判定するしかない…
    }
    • 全部 Exception だと、どの種類かを 文字列で判定 することになる
    • 文字列マッチは壊れやすい
  3. extends Exception で自分の例外クラスを作る

    <?php
    class StockError extends Exception {}
    class PaymentError extends Exception {}
    • ボディは空 ({}) でも OK
    • Exception を継承するので、getMessage() などの機能はそのまま使える
    • これだけで 新しい型 が手に入る
  4. 投げる: throw new MyError(...)

    <?php
    function decrementStock(int $qty) {
        if ($qty <= 0) {
            throw new StockError("在庫がありません");
        }
    }
    • throw new StockError("...") で自作例外を投げる
    • 使い方は標準 Exception と同じ
  5. 受ける: 型で振り分け

    <?php
    try {
        decrementStock(0);
    } catch (StockError $e) {
        echo "在庫エラー: " . $e->getMessage() . "\n";
    } catch (PaymentError $e) {
        echo "支払いエラー: " . $e->getMessage() . "\n";
    }

    実行結果:

    在庫エラー: 在庫がありません
    • 型で区別できるので、メッセージマッチ不要
    • ドメイン固有のエラーを クラス階層 で表現できる
  6. このチャプターでできるようになること

    class MyError extends Exception {} で自作できる ✅ throw new MyError(...) で投げられる ✅ 自作の型で catch できる ✅ ドメイン固有エラーを型で区別できる

    → ドリルへ

1 / 6
📜 スライドを全部一気に読む(縦表示)

Lesson 10 / Chapter 6


標準の Exception だけだと区別がつかない

<?php
try {
    if (在庫不足) throw new Exception("在庫不足");
    if (支払い失敗) throw new Exception("支払い失敗");
} catch (Exception $e) {
    // どっちの例外?
    // メッセージで判定するしかない…
}
  • 全部 Exception だと、どの種類かを 文字列で判定 することになる
  • 文字列マッチは壊れやすい

extends Exception で自分の例外クラスを作る

<?php
class StockError extends Exception {}
class PaymentError extends Exception {}
  • ボディは空 ({}) でも OK
  • Exception を継承するので、getMessage() などの機能はそのまま使える
  • これだけで 新しい型 が手に入る

投げる: throw new MyError(...)

<?php
function decrementStock(int $qty) {
    if ($qty <= 0) {
        throw new StockError("在庫がありません");
    }
}
  • throw new StockError("...") で自作例外を投げる
  • 使い方は標準 Exception と同じ

受ける: 型で振り分け

<?php
try {
    decrementStock(0);
} catch (StockError $e) {
    echo "在庫エラー: " . $e->getMessage() . "\n";
} catch (PaymentError $e) {
    echo "支払いエラー: " . $e->getMessage() . "\n";
}

実行結果:

在庫エラー: 在庫がありません
  • 型で区別できるので、メッセージマッチ不要
  • ドメイン固有のエラーを クラス階層 で表現できる

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

class MyError extends Exception {} で自作できる ✅ throw new MyError(...) で投げられる ✅ 自作の型で catch できる ✅ ドメイン固有エラーを型で区別できる

→ ドリルへ

この章で取り組む 演習問題の流れ (1ステップ)
  1. 01 ドリル 01 — カスタム例外を作って投げて受ける README.md starter.php answer.php

演習問題の詳細

この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。

ドリル 01 — カスタム例外を作って投げて受ける

問題

Exception を継承した MyError クラスを定義してください (中身は空でよい)。

try の中で throw new MyError("自作エラー") を投げ、 catch (MyError $e) の中で "caught: " . $e->getMessage() を 1 行出力してください。

期待される出力:

caught: 自作エラー

ヒント

  • class MyError extends Exception {}
  • throw new MyError("自作エラー");
  • catch (MyError $e) { ... }

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

演習問題(1問)

  1. ドリル 01 — カスタム例外を作って投げて受ける

    README.md starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。

完了にすると進捗に反映されます