例外処理というのはどういった時に使うものなのでしょうか?
if文で対応するのではダメなのでしょうか?
falseを返すことと、例外出すことは基本的に違うと思うよ。
----If(A処理===false) ロールバックIf(B処理===false) ロールバック‥----じゃなくて、----try{ A処理 B処理}catch(エラー){ ロールバック}
A処理(){Throw new エラー(ロールバックしてね)}B処理(){Throw new エラー(ロールバックしてね)}----
もちろん、「ロールバックしてね」以外のエラー投げて、catch内の処理を分けることもできるよね。
関数は値を「返す」が、例外ってのは「投げる」わけ。多重に呼ばれた深いネストの底から一気に抜けて「キャッチ」できることを表現してるわけよ。ifでエラー値を見て判断してたらそれを多重にやることになる。逆に言うとそれだけのことなので無理に使うと煩雑なだけ。特にWebサーバアプリの場合、ネストの底からエラー画面に直接Redirectするのがアリなのであんまり必要性が高くない。dbもcommitしないで接続切れたらrollbackするしな。
ID:leGGe3tNOnEUさんの言うことが的を射ているのでしょう。言語の内部仕様として、例外は例外オブジェクトを返すように表現されているものもあります。ですがそれだと、何か1つ処理を行う関数を呼ぶ度に、例外オブジェクトかどうかチェックして、それならは自身も例外オブジェクトをreturnする、ということをしないといけなくなります。
複数の処理を、1つのメソッド(関数)に定義する時、メソッド内部でさらにメソッド分けるような事がよくあると思うけど、try/catch使えば、メソッド呼び出し側からどこでどんな例外的な事が起きてるか簡単に識別できる。
if分でもできなかないけど、POSTされたデータをバリデーションして、DB登録して、結果をメール通知するみたいな処理とかだと、バリデーションエラーの時はこうして、DB接続エラーならこうで、SQL構文エラーならこうでとかいちいちif分でやるの面倒でしょ。メールとかミドルウェア用のライブラリの内容は基本いじれないし。簡単に言えばこんな感じ?
面倒だからまとめて書いたけど、大体は機能ごとにファイルも分かれてるはず。try/catchなら例外時の処理をまとめて簡単に書けるし、後々修正もしやすい。
<?php
try{doAction();}catch(ValidateException $e){//バリデーションエラー時の処理}catch(DBException $e){//DBエラー時の処理}catch(NoticeException $e){//メール通知エラー時の処理}
/** * POST/GETされたデータをチェックしてDB登録して通知 */function doAction(){ $data = $_REQUEST; $valid_data = doValidation($data);
$result = doInsertDB($valid_data); doNotice($result);
}
/** * データが正しいかチェック、正しくなければValidationExceptionをthrow */function doValidation($data){//省略}
/** * データをDB登録、エラーが起きたらDBExceptionをthrow */function doInsertDB($valid_data){//省略}
/** * メール通知、エラーが起きたらNoticeExceptionをthrow */function doNotice($result){//省略}
ありがとうございます。めちゃくちゃ分かりやすかったです!
みんなの回答 4 件
falseを返すことと、例外出すことは基本的に違うと思うよ。
----
If(A処理===false)
ロールバック
If(B処理===false)
ロールバック
‥
----
じゃなくて、
----
try{
A処理
B処理
}catch(エラー){
ロールバック
}
A処理(){
Throw new エラー(ロールバックしてね)
}
B処理(){
Throw new エラー(ロールバックしてね)
}
----
もちろん、「ロールバックしてね」以外のエラー投げて、catch内の処理を分けることもできるよね。
関数は値を「返す」が、例外ってのは「投げる」わけ。
多重に呼ばれた深いネストの底から一気に抜けて「キャッチ」できることを表現してるわけよ。ifでエラー値を見て判断してたらそれを多重にやることになる。
逆に言うとそれだけのことなので無理に使うと煩雑なだけ。特にWebサーバアプリの場合、ネストの底からエラー画面に直接Redirectするのがアリなのであんまり必要性が高くない。dbもcommitしないで接続切れたらrollbackするしな。
ID:leGGe3tNOnEUさんの言うことが的を射ているのでしょう。
言語の内部仕様として、例外は例外オブジェクトを返すように表現されているものもあります。
ですがそれだと、何か1つ処理を行う関数を呼ぶ度に、例外オブジェクトかどうかチェックして、それならは自身も例外オブジェクトをreturnする、ということをしないといけなくなります。
複数の処理を、1つのメソッド(関数)に定義する時、
メソッド内部でさらにメソッド分けるような事がよくあると思うけど、
try/catch使えば、メソッド呼び出し側からどこでどんな例外的な事が起きてるか簡単に識別できる。
if分でもできなかないけど、
POSTされたデータをバリデーションして、DB登録して、
結果をメール通知するみたいな処理とかだと、
バリデーションエラーの時はこうして、
DB接続エラーならこうで、SQL構文エラーならこうでとか
いちいちif分でやるの面倒でしょ。
メールとかミドルウェア用のライブラリの内容は基本いじれないし。
簡単に言えばこんな感じ?
面倒だからまとめて書いたけど、
大体は機能ごとにファイルも分かれてるはず。
try/catchなら例外時の処理をまとめて簡単に書けるし、
後々修正もしやすい。
<?php
try
{
doAction();
}
catch(ValidateException $e)
{
//バリデーションエラー時の処理
}
catch(DBException $e)
{
//DBエラー時の処理
}
catch(NoticeException $e)
{
//メール通知エラー時の処理
}
/**
* POST/GETされたデータをチェックしてDB登録して通知
*/
function doAction()
{
$data = $_REQUEST;
$valid_data = doValidation($data);
$result = doInsertDB($valid_data);
doNotice($result);
}
/**
* データが正しいかチェック、正しくなければValidationExceptionをthrow
*/
function doValidation($data)
{
//省略
}
/**
* データをDB登録、エラーが起きたらDBExceptionをthrow
*/
function doInsertDB($valid_data)
{
//省略
}
/**
* メール通知、エラーが起きたらNoticeExceptionをthrow
*/
function doNotice($result)
{
//省略
}
関連するトピックス