質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1589閲覧

PHP: functionの中で検知されたPDOExceptionの内容を、当該function呼び出し元で取り扱いたい

saya24

総合スコア221

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/02/09 10:33

functionの中でもDB更新をしていて、PDOのエラーを検知する可能性があります。
呼び出し元でのDB更新部分で検知されるPDOのエラー同様、エラーの取り扱いは呼び出し元で取り扱いたい=呼び出し元で画面構成を行うコーディング部分に活かしたい、と考えています。(呼び出された側で発生したPDOのエラーメッセージを呼び出し元で取得したい)
こういった場合、どういう手続きをとるのが一般的でしょうか?

以下コーディングでは、一般的な例外としてキャッチはできるものの、PDOのエラー詳細まで呼び出し元で取得できないのかな??と思い悩んでいます。
Exceptionクラスの拡張・getPreviousとかいうものを利用してみたかったのですが、よく分からないのでお問い合わせさせて頂きました。

よろしくお願いいたします。
参考を試みたサイト

PHP

1try { 2 3DB更新処理①』、グダグダ直接記載 //errorはPDOEceptionでcatch 4 5 if(DB更新処理②★) != null) { //DB更新処理②は使い勝手よくFunctionにしてる 6 throw new Exception(); //内部ではやはりPDOEceptionでcatchされる 7 } //しかし、呼出し元で上記同様エラー制御をしたい。 8 9 GOTO 正常完了処理へ 10 11} catch (PDOException $e) { 12 error_log('DB更新処理①に失敗'.$e->getMessage(),0); 13} catch (Exception $e) { 14 error_log('DB更新処理②に失敗'.$e->getMessage(),0); 15} 16 17//DB更新処理①でも②でも、エラー目的の処理をここで行う 18//つまりDB更新処理②についても、エラー取扱いは呼出し元で行いたい。 19 20 21functionDB更新処理②★($conn,) { 22 try { 23 $errcd = null; 24DB更新処理②本質』、グダグダ直接記載 //errorはPDOEceptionでcatch 25 return $errcd; //errorなければnullでかえす 26 27 } catch (PDOException $e) { 28 $errcd = 999; 29 return $errcd; 30 } 31}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/02/10 04:43

何をしたいのかいまいち読み取れませんが、DB接続部分に書かれている try 〜 catch ではなく、接続部分の関数を呼び出している関数のところで catch したいということ?
saya24

2019/02/10 05:08

Kosuke_Shibuyaさんお時間を頂き誠にありがとございます。 function呼び出し元で対応することもDB更新(Aテーブル)、functionの中で対応することもDB更新(Bテーブル)。開発の構成上、Bテーブルの更新がfunctionになっているだけのことで、PDOExceptionが別れて定義されている状態です。Function内でPDO系のエラーが生じても、Function呼び出し元でエラー処理を統一しているので、呼び出し元でfunction内部で生じたPDOexceptionについて参照する(getMesseage)方法を教えて欲しい、ということです。 呼び出し元にfunction内部のPDOExceptionの内容を引き継ぎたい、ということですね。呼び出し元のPDOExceptionと呼び出されるfunction内部のPDOExceptionは、別の次元のイメージがあります。 で、function内部で生じたPDOExceptionを呼び出し元へ どう引き継ぐの?という質問になっています。
guest

回答2

0

ベストアンサー

何をしたいのかいまいち読み取れませんが、DB接続部分に書かれている try 〜 catch ではなく、接続部分の関数を呼び出している関数でcatchしたいということですかね?

サンプル

php

1<?php 2 3ini_set('display_error', 1); 4error_reporting(E_ALL); 5 6/** 7 * DB 接続 8 */ 9function connect() 10{ 11 $dsn = 'mysql:host=localhost;dbname=database;charset=utf8mb4'; 12 $username = 'root'; 13 $passwd = 'password'; 14 $pdo = new PDO($dsn, $username, $passwd); 15 $pdo->setAttribute(PDO_ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 16 return $pdo; 17} 18 19/** 20 * 更新処理 21 * @param type $id 22 * @param type $value 23 * @return type 24 */ 25function update($id, $value) 26{ 27 $pdo = connect(); 28 $sql = 'update table set column = ? where id = ?'; 29 $stmt = $pdo->prepare($sql); 30 return $stmt->execute([$value, $id]); 31} 32 33try { 34 update(1, 'test'); 35} catch (Exception $e) { 36 // connect(), update() で発生した例外はここでキャッチできる 37 var_dump($e->getMessage()); 38}

サンプル2

php

1<?php 2 3ini_set('display_error', 1); 4error_reporting(E_ALL); 5 6/** 7 * DB 接続 8 */ 9function connect() 10{ 11 try { 12 $dsn = 'mysql:host=localhost;dbname=database;charset=utf8mb4'; 13 $username = 'root'; 14 $passwd = 'password'; 15 $pdo = new PDO($dsn, $username, $passwd); 16 $pdo->setAttribute(PDO_ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 17 return $pdo; 18 } catch (Exception $e) { 19 // (1)例外をそのままthrow 20 throw $e; 21 } 22} 23 24/** 25 * 更新処理 26 * @param type $id 27 * @param type $value 28 * @return type 29 */ 30function update($id, $value) 31{ 32 $pdo = connect(); 33 $sql = 'update table set column = ? where id = ?'; 34 $stmt = $pdo->prepare($sql); 35 return $stmt->execute([$value, $id]); 36} 37 38try { 39 update(1, 'test'); 40} catch (Exception $e) { 41 // (1)の例外も update() の例外もここでキャッチ可能 42 var_dump($e->getMessage()); 43}

投稿2019/02/10 04:53

編集2019/02/10 05:49
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2019/02/10 05:40

ご丁寧な説明をありがとうございます。 ご提示は一つのtryでのcatchですね。当方のケースでは、tryが処理Aと処理Bの中双方に存在していることの違いがありますね。処理Aに処理Bが含まれている場合、かつ双方にtry・catchが存在しているケースで、処理Bで発生したExceptionを処理Aに引き継げるか?という主旨の質問ですが、kousuke_Shibuyaさんの構成にするのが一般的ですかねぇ
退会済みユーザー

退会済みユーザー

2019/02/10 05:44 編集

いたるところにtry - catch を書いてしまうと、例外を途中で握りうつぶしてしまい、バグの検出が困難になってしまうので、開発案件では禁じ手とするのが普通です。
saya24

2019/02/11 03:06

ご親切な説明をありがとうございました。Throw $eでfuncton呼出し元へ引き継ごうと思えば引き継げるのですね。ただ仰られるようにtry~catchを複数の箇所にコーディングすることに、価値を見出せなくってきた自分がいるので方針を改めたいと思います。大変参考になるアドバイスをありがとうございました。
guest

0

マニュアルの User Contributed Notes を覗いてみてください。
参考になる記述がいくつかあります。

ざっくりというと、catchでさらに例外をthrowしてやればよいです。

php

1try { 2 $PDO = new PDO( '...' ); // PDO Driver DSN. Throws A PDOException. 3} 4catch( PDOException $Exception ) { 5 // Note The Typecast To An Integer! 6 throw new MyDatabaseException( $Exception->getMessage( ) , (int)$Exception->getCode( ) ); 7}

投稿2019/02/09 10:45

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2019/02/09 14:06

お時間を頂きまして誠にありがとうございます。 ご想像以上に初心者で申し訳ないのですが、ご見解はfunction側のcatchでthrowをする、というアイデアでしょうか?ご提示のようにして当該function呼び出し元に、PDOExceptionがまるっと戻るのでしょうか?? function側で、PDOExceptionを継承するクラス(extendsする)を作っておいて、function内の・PDOExceptionのcatch時には その継承クラス丸っとfunctionの戻り値にする、とかでしょうか?functionが戻り値からしか挙動結果をうかがい知れないと思っていて。(getPreviousとかいうクラスがあるのはちょっと気になっているのですが)
退会済みユーザー

退会済みユーザー

2019/02/09 14:51

ちょっと何言っているかわかりません。試してみれば?
saya24

2019/02/10 03:52

throw new MyDatabaseException( $Exception->getMessage( ) , (int)$Exception->getCode( ) ); をfunction側のcatch内に挿入しましたが、MyDatabaseExceptionが見当たらないみたいなコーディング上のエラーになってしまいます。 呼び出しもとのcatchに入れるのでしょうか? functionの中で class MyDatabaseException extends PDOException とか記述するのでしょうか? ご想像以上に初心者で申し訳ないです
退会済みユーザー

退会済みユーザー

2019/02/10 06:26

> functionの中で class MyDatabaseException extends PDOException とか記述するのでしょうか? うーん。多分 php の基礎的なところで学習が足りてないです。 object とか class とか instance とかちゃんと学習しないとちゃんと書けないです。 例外に関しては以下の資料を見てみると面白いです。 https://speakerdeck.com/twada/php-conference-2016?slide=99
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問