はじめに
PHPでは、try-catch 構文を使って例外処理を行います。しかし、「複数の catch ブロックを並べた場合、どれが実行されるのか?」という挙動を誤解していると、テストで間違いやすいポイントになります。
今回は、「例外クラスの継承構造」と「catchブロックの実行順序」を図解でわかりやすく整理します。
目次
🎯 結論から言うと…
複数の catch
ブロックは 上から順にマッチ判定され、最初に一致したブロックだけが実行 されます。そのため、親クラスを先に書くと、子クラスのcatchはスキップされます。
🧩 例外階層のイメージ図(ASCIIアート)
Throwable (interface)
├── Exception implements Throwable
│ ├── LogicException
│ └── RuntimeException
└── Error implements Throwable
つまり:
RuntimeException
はException
の子クラスException
はThrowable
を実装している
🧪 実験コード
<?php
declare(strict_types=1);
error_reporting(-1);
try {
throw new RuntimeException("any runtime exception");
} catch (Throwable $e) {
echo "Throwable \n";
echo $e->getMessage(), "\n";
} catch (Exception $e) {
echo "Exception \n";
echo $e->getMessage(), "\n";
} catch (RuntimeException $e) {
echo "RuntimeException \n";
echo $e->getMessage(), "\n";
}
💥 実行結果
Throwable
any runtime exception
🧠 解説(なぜそうなる?)
throw new RuntimeException(...)
により、例外オブジェクトが投げられる- PHPは上から順に
catch
の型をチェックする RuntimeException
はThrowable
の子孫クラス → したがって最初のcatch (Throwable $e)
にマッチ- 一致したブロックが実行された時点で処理は終了するため、以降のcatchは無視される
✅ 正しい順番に並べた例
具体的なクラス → 抽象的なクラス の順で書くのが正解です。
try {
throw new RuntimeException("any runtime exception");
} catch (RuntimeException $e) {
echo "RuntimeException \n";
echo $e->getMessage(), "\n";
} catch (Exception $e) {
echo "Exception \n";
echo $e->getMessage(), "\n";
} catch (Throwable $e) {
echo "Throwable \n";
echo $e->getMessage(), "\n";
}
実行結果:
RuntimeException
any runtime exception
📘 試験対策ポイントまとめ
項目 | 内容 |
---|---|
catch の評価順 | 上から順にチェックされる |
複数catchの原則 | 子クラス → 親クラスの順で書く |
Throwable | Exception, Error すべてを捕まえる最上位 |
よくあるミス | 親クラスを上に書いてしまい、子catchが無視される |
💡 まとめ
- 例外の継承構造を理解しておくことが重要
- PHPの
catch
は最初に一致したものしか実行されない - 実務でも「順番ミス」でデバッグが難航するケースあり
- 試験問題では「どのcatchが実行されるか?」を正確に追えるようにしておこう