PDOでのtry~catch構文の使い方とは?

このQ&Aのポイント
  • PHP5のPDOは、try~catch構文に対応しています。どのように使えば良いのでしょうか?SQLを発行するメソッドの度にtry~catchが必要なのか、例外処理を行わずに放置しても問題はないのか疑問です。
  • 現時点では、例外が発生した場合には、単にtrigger_errorでエラーメッセージを表示しています。しかし、そのまま放置しても問題ないのか不安です。
  • 正しい使い方や最適な例外処理の方法を教えていただきたいです。
回答を見る
  • ベストアンサー

PDO で try~catch 構文を使う場所は?

PHP5のPDOはtry~catch構文に対応しているのですが、どのように使えばいいのでしょうか? SQLを発行する度に、もしくはSQLを発行するメソッドの度に、try~catchしなければいけないのでしょうか?とても面倒です。 現時点では、例外が発生した時にする処理といえば、 trigger_error($e->getMessage(), E_USER_ERROR); みたいに、trigger_error するだけです。 であれば、そもそもcatchせずに、uncaught のまま勝手にエラったままに放っておいても問題ないのでしょうか? よろしくお願いいたします。

  • PHP
  • 回答数1
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
  • hrm_mmm
  • ベストアンサー率63% (292/459)
回答No.1

try{ }catch{ }は、トランザクションに対応しているデータベースへ接続するときに、真価を発揮します。たとえば、SQLite3 や MySQL5.0などです。 insert文や、update文などデータを変更するSQL文を発行する前に、 PDO::beginTransaction() とし、以降の処理をtry構文内で行います。 途中でエラーがあった場合に、catch構文内へ処理が飛び、そこで PDO::rollBack() を呼ぶと途中までの処理をキャンセルすることができます。 エラーが無ければ、try構文の最後に PDO::commit() を発行して、全ての処理を有効にします。 http://jp.php.net/manual/ja/pdo.transactions.php manual に例文もありますのでよく読んで使ってみて下さい。 select文では、データに変更が無いので、PDO::rollBack() しても意味がありません。 また、MySQL4.0では、トランザクションに対応していないので、PDO::rollBack() を呼ぶと致命的エラーとなってしまいます。 これらでは、try{ }catch{ } よりは、例外キャッチ関数を使う方が、エラー時の処理が一カ所に集約されるのでよいでしょう。 いずれの操作も行わずエラー放置というのは、プログラムの異常終了を招いたうえに、何でエラーが出てるのか解らなくなったりしますので、よくないと思います。 例外キャッチ関数を使うには、PDOのエラーは、例外を投げるモードにしておいて(他の通常のエラーと区別しやすくする) PDO::setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) さらに、例外をキャッチする関数を定義しておくと、どこで例外が発生しても、エラー表示用の記述は一カ所で済みます。 ーーー記述例 <?php function exception_handler($e){ print '<div style="border:red 3px double;"><em>エラー</em> '.$e->getMessage() . '</div>'; } set_exception_handler('exception_handler') ; $dbh = new PDO('sqlite:sql_db', '', ''); if( ! is_object( $dbh) ){ echo "接続エラー"; exit; } echo "接続しました\n"; $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 以降、いろいろ操作、PDOのエラーが出たときは、exception_handler() が実行される。 // rollBackの必要性がなければ try文は不要。 // try文を書いたなら、exception_handler()は呼ばれなくなるので、catchしなければならない。 ?>

参考URL:
http://jp.php.net/manual/ja/book.pdo.php
sweepea
質問者

お礼

ご回答ありがとうございます。 MySQL5ですので、トランザクションを使っております。その際には、もちろん、catch して、rollBackしております。 それ以外の場合は、trigger_error するだけなので、try~catchは行数もかさんで邪魔だなと思っていたのですが、exception_handler で捕捉してやればいいのですね。ありがとうございました。 他の方の意見も聞いたのですが、捕捉されない例外はuncaught exception エラーを起こすので、捕捉後trigger_error するくらいなら、そのまま放置してもよいとの答えでした。 ありがとうございました。

関連するQ&A

  • try~catch

    php初心者です try~catchをわかりやすく教えてください throw new Exceptionが出現したら、catchまでの処理をしないでとばすとゆうことですか? try~catchを抜けたら、他の処理は普通に実行されるのでしょうか? try~catchのカッコ{で囲む範囲は大きくしたほうがいいでしょうか?(大きく囲むと処理スピードおそくなりますか?) try { throw new Exception('エラーが発生しました');  print "hoge"; } catch (Exception $e) {  echo '例外発生', $e->getMessage(), "\n"; }  print "foo"; よろしくお願いします

    • ベストアンサー
    • PHP
  • try~catchについて

    プログラム初心者です 繰り返し処理の中でtry~catchにスローしてもいいでしょうか?(正常にfor文は終了しますか?) try { for($a = 0; $a < 5; $a++) { if($a==3){ throw new Exception('3'); } } catch (Exception $e) { $msg = $e->getMessage(); } よろしくお願いします

    • ベストアンサー
    • PHP
  • pdo

    個別で指定がない限り全体のsetFetchModeを最初に定義したいのですがエラーになってしまいます。 マニュアル等も見たのですがいまいち理解できず質問させて頂きました。 全体の指定をするにはどのように書けばいいでしょうか?以下現在のソースです。 また、pdoは初めて使用するのですがその他に定義しておいたほうがいい定数等がありましたら 是非アドバイスをお願い致します。 (自分で思いつくのは文字コードとフェッチモード程度でした^^;) $sql = "SELECT * FROM table where id = ?"; try { $pdo = new PDO($dsn, $user, $password); if ($pdo == null){ print('接続失敗'); } //$pdo->setFetchMode(PDO::FETCH_ASSOC); $pdo->query('SET NAMES utf8'); $stmt = $pdo->prepare($sql); if ($stmt->execute(array(1))) { while ($row = $stmt->fetch()) { print_r($row); } } } catch (PDOException $e) { print('Error:'.$e->getMessage()); die(); } $pdo = null;

    • 締切済み
    • PHP
  • Try-catch文(FileInputStream)

    下記コードでエラーが出現して困っています。 fis.close();の部分でコンパイルエラー( 変数 fis は初期化されていない可能性があります。)の結果が返ってきます。 必ず通過するfinallyブロックにclose()処理を記述して、この処理もエラーが発生する可能性があるので、try-catchする必要があると教師が言っていました。 エラーが出現する原因はなぜでしょうか? 回答のほどよろしくお願い致します。 FileInputStream fis; try{ fis = new FileInputStream(fi.getAbsolutePath()); while( (b[i++] = fis.read()) != -1); }catch(FileNotFoundException e){ } catch(IOException e){ }finally{ try{ fis.close(); ←コンパイルエラー( 変数 fis は初期化されていない可能性があります。) }catch(IOException e){ } }

    • ベストアンサー
    • Java
  • try catchについて

    try catchの動きで質問があります。 以下が簡略化したソースです。 -------ここから--------------------- ストリーム1; ストリーム2; try{ try{ //ストリーム1を使った処理 }catch(IOException e){ throw e; }finally{ //ストリーム1のクローズ } try{ //ストリーム2を使った処理 }finally{ //ストリーム2のクローズ } } catch(IOException e){ throw new hogeException(); } ------ここまで-------------------------- 内側でスローされた例外は、外側でcatchされるのですか? また、内側でcatchをしなかった場合、外側でcatchされるのですか? この2点を教えていただきたいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • try~catch構文は、どういうメリットがあるのですか?

    以下は 関数 hoge に失敗したら、例外を補足するコードです。 try {   if (!hoge()) {     throw new Exception('hogeに失敗しました');   } } catch (Exception $e) {   echo $e; } 以下のように書いたほうが分かりやすいと思いますが、 駄目なんでしょうか? hoge() || die('hogeに失敗しました'); ちなみに、DBのトランザクションを利用して、何かに失敗したら、 catch 以下でロールバックするのは便利だと思います。 しかし、こういう場合以外で、try~catch構文を使うメリットは何でしょう?

    • ベストアンサー
    • PHP
  • 継承クラスで定義したメソッドのtry-catch文

    親クラスで、子クラスで実装されたメソッドのExceptionをキャッチしたいのですが、 うまくいきません。 何か良い方法はないでしょうか? abstract class A { public __construct(){ try{ $this->testA(); }catch(Exception $e){ var_dump(1); } } abstract function testA(); } class B extends A { function testA(){ throw Exception('test',1); } } try{ new B; }catch(Exception $e){ var_dump(2); // こっちが動く } よろしくお願いします。

    • ベストアンサー
    • PHP
  • PDOを使いたい

    PHP初心者です PHP 5.2.5 MySQL 5.1.22 PDOでMYSQLに接続するにはどうすればいいのでしょうか? いままではこんな感じでしたがPDOにするとどんな感じになるんですか? $link=mysql_connect('localhost', 'user', 'pass')or die(mysql_error()); mysql_select_db(user'); mysql_query('SET NAMES UTF8'); PDOで接続する方法らしいのですが疑問を持ってしまったので教えてください 質問1 最初の$db_nameや$passなどの変数のとこに直接、localhostと書くのはまずいですか? 質問2 古いMYSQL系はカッコで囲めばいいので簡単だったのですがPDOの記号の意味を教えてください->とか=>です 質問3 PDO::ATTR_EMULATE_PREPARESは指定する必要があるんでしょうか?指定しないとパフォーマンスが下がるんですか?PDO::ATTR_EMULATE_PREPARESとはなんでしょうか? try { $pdo = new PDO("mysql:dbname=$db_name;host=$serv","$user","$pass", array( PDO::MYSQL_ATTR_INIT_COMMAND => "SET CHARACTER SET 'utf8`")); } catch (PDOException $e) { die($e->getMessage()); } よろしくお願いします

    • ベストアンサー
    • PHP
  • ODBCによるSQL serverへの接続方法を教えてください。

    PHPでSQL ServerへのODBC接続をしたいのですが、SQL Serverの場合の例がみつけられません。以下の~部分を教えてください。 try{ $db=new PDO("~"); $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); print('データベースへの接続を確立しました。'); }catch(PDOException $e){ die("エラーメッセージ:".$e->getMessage()); } ※SQL ServerへはWindows認証で接続しています。 PHP使用環境  OS:Windows2000 pro  PHP:5.1.6  ODBC:登録済み(Windows認証、登録時の接続テスト正常終了)  ※SQL Serverはリモートサーバ。

    • 締切済み
    • PHP
  • php,sqlのテーブル作成について

    php,sql文について質問があります。 現在、テキストボックスに文字を入力したら、DBにその名前のテーブルを新規作成するプログラミングに挑戦中なのですが、 以下のプログラミングでは、テーブルが作成されません どこ を直したらいいのでしょうか? php,sqlに詳しい方どうかご教授お願い致します。 <?php try{ $dbh = new PDO('mysql:host=localhost;dbname=aaaa','bbbb','cccc'); }catch (PDOException $e){ var_dump($e->getMessage()); } $stt = $db->prepare('CREATE TABLE date( abcID char(6) )' ); echo'テーブルを新規作成しました'; ?> ちなみに以下のプログラミグでデーターベースに接続出来ることは確認しております <?php try{ $dbh = new PDO('mysql:host=localhost;dbname=aaaa','bbbb','cccc'); } catch(PDOException $e){ var_dump($e->getMessage()); exit; } echo'DBに接続しました'; ?>

    • 締切済み
    • PHP

専門家に質問してみよう