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

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

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

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

16748閲覧

PHP、PDOの例外処理について

erika.m

総合スコア47

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

4クリップ

投稿2016/11/24 06:56

PDO利用時の例外処理について
調べてもどれがベストなのか、正解が出てこなかったので質問させてください。

PDOのエラー発生時に例外を投げるように設定しています。

PHP

1try { 2 $pdo = new PDO($dsn, $user, $pass, $options); 3 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 4 5 // なんかの処理 6 7} catch (PDOException $ex) { 8 // 例外処理 9}

とした場合、順序として

  1. エラー発生時、自動的にPDOがPDOExceptionを投げる
  2. 投げられたPDOExceptionをcatchで受け取る

ということは理解しました。

しかし、本やネットによっては

PHP

1try { 2 $pdo = new PDO($dsn, $user, $pass, $options); 3 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 4 5 // なんかの処理 6 7} catch (Exception $ex) { 8 // 例外処理 9}

としているところもありました。(Exceptionを受け取っている)

継承の関係でExceptionでも受け取れる
ということも、なんとなく…、ですが一応理解しました。

じゃあ、catch時、Exceptionで受け取った場合とPDOExceptionで受け取った場合の違いって、一体何なんでしょうか?
どちらで書くべきですか?


それとすみません、関連した質問として
VBAのGotoステートメントのように例外を分けたいのですが

PHP

1try { 2 // なんかの処理 3 if ($err1) throw new Exception("", 10); 4 if ($err2) throw new Exception("", 20); 5 if ($err3) throw new Exception("エラーが発生しました。", 99); 6 7} catch (Exception $ex) { 8 // 例外処理 9 if ($ex->getCode() === 99){ 10 echo $ex->getMessage(); 11 } else{ 12 header("HTTP/1.0 404 Not Found"); 13 exit(); 14 } 15}

といった感じで
投げたCodeで処理を分けるのって、一般的に見てアリですか?
(イマイチExceptionの使い方が分からなかったので…)

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

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

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

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

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

guest

回答3

0

ベストアンサー

複数型のExceptionそれぞれ別々にCatchしたい場合以下のようにしてください。

PHP

1try { 2 $pdo = new PDO($dsn, $user, $pass, $options); 3 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 4 // なんかの処理 5} catch (PDOException $ex) { 6 // PDOExceptionをCatchしたときの例外処理 7 // DB接続ができなかったのでDBのCloseなどは不要 8} catch (Exception $ex) { 9 // ExceptionをCatchしたときの例外処理 10 // 「なんかの処理」でファイルオープンに失敗していた。 11 // PDOExceptionじゃ無かったのでDBへの接続はできている。 12 // DBのClose処理が必要 13}

以下のように書くとすべてのExceptionをcatchします。

PHP

1try { 2 $pdo = new PDO($dsn, $user, $pass, $options); 3 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 4 // なんかの処理 5} catch (Exception $ex) { 6 // すべてのException(PDOExceptionも含む)をCatchしたときの例外処理 7}

それとすみません、関連した質問として
VBAのGotoステートメントのように例外を分けたいのですが
・・・略・・・
投げたCodeで処理を分けるのって、一般的に見てアリですか?

局所的なものなら問題ないんじゃないですかね?
以下のように自分でExceptionを作成することもできます。(実行確認してませんのであくまで参考です。)

PHP

1class SystemException extends Exception { 2 public function __construct(){ 3 parent::__construct('500 Internal Server Error'); 4} 5 6class NotFoundException extends Exception { 7 public function __construct(){ 8 parent::__construct('404 Not Found'); 9} 10 11try { 12 if ($err1) throw new NotFondException(""); 13 if ($err2) throw new NotFondException(""); 14 if ($err3) throw new SysFondException(""); 15} catch (NotFoundException $nfex) { 16 header("HTTP/1.0 " . $nfex->getMessage()); 17 exit(); 18} catch (SystemException $sysex) { 19 header("HTTP/1.0 " . $sysex->getMessage()); 20 // エラーログ出力など 21 exit(); 22}

投稿2016/11/24 07:04

編集2016/11/24 07:33
Y.H.

総合スコア7918

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

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

0

私も「Exceptionで受け取った場合とPDOExceptionで受け取った場合の違い」について気になります。

同じく勉強中でして、直接的な回答ができなく申し訳ないです。

PHPマニュアルの「例外」には下記の記述があります。

スローされるオブジェクトは、ExceptionクラスあるいはExceptionのサブクラスのインスタンスでなければなりません。それ以外のオブジェクトをスローしようとするとPHPの Fatal Error が発生します。

Exceptionに関しては下記の記述があります。

Exception は、PHP 5 ではすべての例外の基底クラスです。 PHP 7 では、すべてのユーザー例外の基底クラスとなります。

PDOExceptionはExceptionを継承した子クラス(サブクラス)です。
そのため、ExceptionクラスとPDOExceptionクラスはスローするオブジェクトとして指定できます。

ここまで質問に記載されておりますので、ご存じかと思います。

この2つの違いですが、例外には種類があります。

イメージ説明

引用:PHP7で堅牢なコードを書く - 例外処理、表明プログラミング、契約による設計

主にLogicException系とRuntimeException系があります。
それぞれの違いは下記の通りです。

LogicException … 自身のコード,あるいはそれを利用している第三者のコードにバグがあることを示す例外.
RuntimeException … 正しく取り扱っていても起こりうる例外.

引用:お前は PHP 7 における Fatal Error / Catchable Fatal Error / Error / ErrorException / Exception の違いを言えるか?

おそらく、何の例外か使い分けるためなのかと思います。
ただ、勉強中の素人でして、実例を出して使い分けることでこのようなときにこのようなメリットがあると示すことができません。
ですので、あくまでも推察になります。

どちらで書くべきですか?

上記に関してですが、PDOクラスは「指定されたデータベースへの接続に失敗した場合、 PDOException を投げます。」とPHPマニュアルに記載されております。

データベース接続に関しての例外は、PDOExceptionを使う方が良いのではないかと考えております。

あくまで、私の推察であり実例を示した根拠がありません。
上記に関して、エンジニアの方々、識者の方々の意見が出てくれば、そちらを優先してください。
また、私の回答に誤りなどあれば、ご指摘ください((_ _ (´ω` )ペコ

投稿2016/11/24 10:51

編集2016/11/25 00:27
7968

総合スコア253

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

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

0

Exceptionで受け取った場合

Exceptionで受け取るんですからPDO以外の例外処理も受け取れるでしょう

PHP

1set_error_handler('myErrorHandler'); 2function myErrorHandler($errno, $errstr, $errfile, $errline) 3{ 4 switch($errno) { 5 case E_NOTICE: 6 throw new exception("common notice:".$errstr."<br>"); 7 break; 8 case E_USER_NOTICE: 9 throw new exception("my notice:".$errstr."<br>"); 10 break; 11 default: 12 return false; 13 } 14 return true; 15}

的な定義をしておいて

PHP

1try{ 2 if(!isset($a)) trigger_error("no a!",E_USER_NOTICE); 3}catch(exception $e){ 4 print $e->getMessage(); 5} 6 7try{ 8 print $a; 9}catch(exception $e){ 10 print $e->getMessage(); 11}

など場合分けができます

投稿2016/11/24 07:12

yambejp

総合スコア116810

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問