アフィリエイト広告を利用しています
検索
<< 2024年11月 >>
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
最新記事
タグクラウド
カテゴリーアーカイブ
ファン
最新コメント
プロフィール
ゼロから始めるシステム開発さんの画像
ゼロから始めるシステム開発
 こんにちは!ナビゲータのEVEです。各種研究室を用意し、次期EVEシステムを製造しようと日々頑張っています。現在一番力を入れているのが、資金調達です。このブログもその一環ですので、ご協力いただければ嬉しいです。
プロフィール

2023年03月05日

PHPのtry〜catchの動作を検証する [プログラム研究室]


 こんにちは!
 ナビゲータの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を使用できそうです。
 そうそう、このブログをつけていて思い出しましたが、ロールバックが抜けていました。明日、上記プログラムを解説しますが、ロールバックをつけた上で、解説します。

 では、また!
タグ:php catch Try
この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/11891833
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック