PHPの例外処理ってどうだっけ?〜バケツリレーで思い出す〜

今回はPHPの例外処理を復習してみました。前に一回勉強したはずなんだけど仕組みの理解がちょっと怪しいんですよね……「throwで投げてcatchで拾う」までは覚えてるけど、そのあとどうなるんだっけ?ってなって再学習中です。
1. そもそも例外って?
PHPでエラーが起きたとき、try
/ catch
を使えば、プログラムを止めずに処理を続けられます。
try {
// なにか問題が起こるかもしれない処理
throw new Exception("問題発生!");
} catch (Exception $e) {
echo "エラーをキャッチしました: " . $e->getMessage();
}
throw
で例外を投げて、catch
で受け取る。
はい、これはOK。それは覚えてた。
2. で、catchされなかったらどうなるの?
ここがちょっとあやふやだった部分。
「どこかでcatchされなかったらどうなるんだっけ?」と思ってたら、
例外って、実はどんどん上に伝わっていくんですよね。
そのイメージがしっくりきたのが、「バケツリレー」って例え。
3. 例外の伝播 = バケツリレー
こんなコードがあるとします。
関数が関数を読み込むマトリョーシカ構造のコードです。
function step3() {
throw new Exception("step3でバケツ(例外)投げた!");
}
function step2() {
step3(); // ここではキャッチしない
}
function step1() {
try {
step2();
} catch (Exception $e) {
echo "step1がキャッチした!: " . $e->getMessage();
}
}
step1();
step3でバケツ(例外)投げた! -> step1がキャッチした!って流れ。
ここで、一番下の「step3」
で例外が投げられたとします。「step2
」はというと、何も書かれていません。つまりスルーしています。
「ん?なんか来たけど自分じゃ無理だから次の人お願い〜」って感じで、
「step1」
にバケツを渡している状態です。で、「step1」
がキャッチ。
「step1」
が「あいよ〜」って拾って
ここで処理するって流れというわけですね。
こうして例外は「どこかで誰かがキャッチしてくれるまで」上に上に流れていく。
これがバケツリレー的な伝播です。
4. 誰も受け取らなかったら?
そのまま最後まで誰にもキャッチされなかったら、
「Uncaught Exception」っていう、いかにもまずそうな赤文字エラーが出ます。
PHPは「投げっぱなしで誰も拾ってくれなかった!」って怒る感じ。
なので、必ずどこかでエラー処理をしなくちゃいけないんですよね。
ちなみに「Exception」以外にも、独自の例外クラスを使ったり、finally
を使ったりする方法もあるので、そのうちピックアップしてみようと思います。
ちなみにcatchして何もしないことを
「エラーを握りつぶす」というらしいですね。
まとめ. 昔ちょっとわかった気になってたけど…
throw
で例外を投げるcatch
でキャッチする(これだけじゃ足りない)- キャッチされなければ、どんどん上に伝わっていく
- 最終的に誰も受け取らなければエラーで止まる
例外処理って、ちゃんと理解しておくとデバッグもしやすくなるし、
「どこで何が起きたのか」が分かりやすくなるなぁと、あらためて納得できました。
今回は以上です!