こんにちは!
ナビゲータのEVEです。
catchって、直前のエラーを拾うんでしたっけ?それともtryの中の例外すべて拾うんでしたっけ?っていう疑問を持ったので、本日は、実際に動いているプログラムから検証してみました。
[検証方法]
検証方法は、どこを通っているのかどうか分かるように、プログラムにechoを入れ、画面から確認するという方法です。プログラムにechoを入れるというのは、下記の紫の部分のロジックになります。
/*************************************************
*【メソッド名】レコード追加メソッド
*【 引 数 】dbName :データベース名
* i_Clum :カラム名(配列)
* i_Data :データ(配列)
*【返 却 値】
* 正常時:true
* 異常時:False
*【製 造 者】EVE
*【製造年月日】2023年3月3日
*【更新年月日】
*【 概 要 】
* [2023/03/03]
* レコードを追加する
*<注意>
*@トランザクションを開始したくない場合は、開始前に
*トランザクション開始プロパティにoffを設定
*Aコミットしたい場合は、本メソッド開始前に、
*処理確定プロパティにonを設定
*************************************************/
//レコードを追加する
public function recInsert(string $dbName, //データベース名
array $i_Clum, //追加用項目
array $i_Data) { //追加データ
//❶変数定義
static $i; //ループインデックス
static $i_array = array(); //追加用配列
static $strSql; //SQL文
//❷引数の判定を行う
if ( count( $i_Clum ) != count($i_Data) ) {
//引数の指定に誤りがある場合
$this->processMessage = "引数の指定に誤りがあります";
//呼び出し元へ制御を移す
return false;
}
//❸トランザクションを開始フラグを判定する
if ( $this->setTran == "on" ) {
//トランザクション開始する
$this->setTran();
//トランザクション開始プロパティを実行中にステータスを変更する
$this->setTran = "exe";
}
//❹SQL文を編集する
$i_array[] = "insert into ";
$i_array[] = $dbName;
$i_array[] = " (";
//カラム配列終了まで以下の処理を実行する
for ( $i = 0; $i < count( $i_Clum ); $i++ ) {
//カラムを編集する
$i_array[] = $i_Clum[$i];
//最終処理かどうか判定する
if ( count( $i_Clum ) == $i + 1 ) {
//最終処理の場合
$i_array[] = ")";
//forを終了する
break;
} else {
//最終処理でない場合
$i_array[] = ",";
}
}
//データの編集を開始する
$i_array[] = " value (";
//データ終了まで以下の処理を実行する
for ( $i = 0; $i < count( $i_Data ); $i++ ) {
//データを編集を開始する
$i_array[] = "?";
//最終処理かどうか判定する
if ( count( $i_Data ) == $i + 1 ) {
//最終処理の場合
$i_array[] = ");";
//forを終了する
break;
} else {
//最終処理でない場合
$i_array[] = ",";
}
}
//SQL文を編集する
$strSql = implode( "",$i_array );
//❺プリシェアードステートメント設定する
$this->stmt = $this->getDbConnect->prepare($strSql);
//SQL文実行処理
try {
echo "check01";
//❻バインド変数終了まで以下の処理を実行する
for ( $i = 0; $i < count($i_Data); $i++ ) {
//データをSQL文へ設定する
$this->stmt->bindParam($i+1,$i_Data[$i]);
}
//❼レコード追加メソッドを実行する
$this->stmt->execute();
echo "check02";
} catch (PDOException $e) {
echo "check03";
//検索が失敗した場合
//❽異常処理結果のメッセージを設定する
$this->processMessage = $e->getMessage();
//返却値を設定して呼び出し元へ制御を移す
echo "check04";
return false;
}
//❾コミットするかどうか判定する
if( $this->setCommit == "on" ) {
//プロセス確定メソッドを実行する
$this->setCommit();
}
echo "check05";
//返却値を設定し呼び出し元へ制御を移す
return true;
}
[正常系の検証]
データを設定し、実行しますと、想定してたとおり、
check01
check02
check05
というルートを通ります。
[異常系の確認]
異常系は、正常系の試験を終えた後、データベースに同データが残った状態で、キーが重複するデータを再登録することにより検証しました。その場合も予想通りの結果となります。
check01
check03
check04
[catchの前にロジックを入れてみる]
❾の「コミットするかどうか判定する」のif文を❼の次にロジックを持ってきて、処理を実行しました。その結果は、
check01
check03
check04
となります。エラーの時の状況で分かりにくいので、❾の「コミットするかどうか判定する」のif文を、echo "check02-1";と、echo "check02-2";ではさんで、以下の形で実行すると、以下のようになります。
check01
check03
check04
//レコード追加メソッドを実行する
$this->stmt->execute();
echo "check02-1";
//コミットするかどうか判定する
if( $this->setCommit == "on" ) {
//プロセス確定メソッドを実行する
$this->setCommit();
}
echo "check02-2";
[結論]
検証の結果は、catchの直前でなくても、エラーは拾ってくれるということは分かりました。但し、エラーが発生した時、エラー以降に実行したい処理があっても、その処理は実行されずcatchへ飛んでしまいます。加えて、try、catchとも、同ロジック内にreturnなどがなければ、try、catchのロジックを抜け、次の処理にいきます。
以上の検証で、これから、迷うことなく、try、catchを使用できそうです。
そうそう、このブログをつけていて思い出しましたが、ロールバックが抜けていました。明日、上記プログラムを解説しますが、ロールバックをつけた上で、解説します。
では、また!
【このカテゴリーの最新記事】