taitokissの備忘録

調べたことを忘れないように書き留めています。

PHPの例外処理って?

PHPMySQLデータベースに接続する (PDO 編)を書く前に、ここで使う「例外処理」についてちょっと考察しておきたい。

 

例外(Exception)処理

例外処理って何?

「例外」≒「エラー」

と考えればいいのかな?

 すなわち、「例外処理」とは「エラー処理」のことか。

 予期しない結果が発生した(エラー)時に強制的に別の処理をすることである。

 例えば、データベースに接続できない、数値計算でゼロ除算した、ユーザー入力値が不正の場合など、正常で無い事が起きた場合にそれを復旧する処理のことのようだ。


「エラー処理」なら一般的に「if文」など分岐処理で対応できるが、PHP5以上では「try ~ catch 文」が使用できる。
しかし、「if文」に代えて、「try ~ catch 文」を使うメリットがよく分からない。
どちらでもエラー処理できるのなら使い慣れた「if文」で十分ではないのだろうか。
ネットで調べると、使用するメリットとしてはエラーの対処が簡単になるとか、読みやすいコードが書けるとか書いてあるが、初心者からしたらこう書かれてもピンとこない。

さらに何か理解を助けることが書かれていないか、ネットを徘徊した。

そして、私なりに解釈してみた。

「エラー処理」を「if文」を使って考える時、どのようなエラーが出るかを一つ一つ考えながらそのエラー対応のコードを書いていく。しかし、ある一つの処理に対して想定できるエラーならこの方法で十分だが、考えが及ばないエラーもある。また、全てのエラーを予想することは手間が掛かる。

上で書いたことを振り返ると、「予期しない結果が発生した(エラー)時に強制的に別の処理をすること」
すなわち、「想定外のエラー時」の処理のことを例外処理と言っているのだ。

繰り返すが、予め想定できれば「if文」で場合分けして書けるが、考えが及ばない時は予期しないエラーが起こり得るのでそれに対処できるわけである。

どうも日本語の解釈の問題のようである。

但し、

「try~catch」は「Exception」オブジェクトを利用した例外処理が実装されているわけで、

Exceptionクラスは、基本的に関数やメソッドの中で問題発生時にthrowして利用する。
そして、例外処理を含む関数/メソッドをtryブロック内で実行することで、例外が発生したときにcatchブロックに捕捉される。

<?php
function div($val1, $val2) { //割り算
if ($val2 == 0){
//例外発生
throw new Exception("ゼロ除算");
}
$ans = $val1 / $val2;
return $ans;
}

try {
$ans = div(10, 0);
} catch (Exception $e) {
echo "エラー:" . $e->getMessage(); //メッセージ表示
//ここでエラー回復処理
}

//次の処理
echo "--- Exception Test ---";
?>

上のように使うようだが、何か変?
というのは、「if文」で「$val2 == 0」の時に throw しているが、「if文」で判断する例外時の条件は自分が考えなくてはいけない。
これでは、「予期しないエラー」ではなく「予期するエラー」という事になる。
「try ~ catch 文」を使うメリットは、想定できないエラー時に威力を発揮するはずなのに。

掘り下げて考えてみると、
PHPの内部関数には例外処理に対応しているものがある。
これらの関数を使用した時に、予期しえないエラーが起こると「Exception」オブジェクトを返してくる。

これと違うかな?

例えば、

$dbh = new PDO($dsn, $user, $password);

と、PDOクラスのオブジェクトを作成した時、

「コンストラクタ PDO::__construct() は、 指定されたデータベースへの接続に失敗した場合、 PDOException を投げます。」

PHPマニュアルにはある。

これなら自分で場合分けしてコードを書く必要なくエラーが捉えられるわけだ。「if文」を使う必要がない。

結局、上の様に例外処理に対応した内部関数を使って例外処理をすることにメリットがあるのではないのだろうか?

但し、PHPの内部関数の多くは例外処理に対応していないので、 使用できるのは例外処理を実装した新しいオブジェクト指向の拡張モジュールのみになるようだが。

例外処理に対応していない場合でもErrorExceptionを使えばエラーを例外に変換することができるようだが、これもエラーを把握しておく必要があるな。ErrorException に関してはまた別に調べたい。