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

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

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

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

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

解決済

1回答

2165閲覧

常に例外を取るべきか取らないべきか

aaaaaaaa

総合スコア501

PHP

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

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

2クリップ

投稿2016/07/04 11:27

下記のソースは、データベースへ接続するときに例外が発生した場合、例外処理が発生するものです。

php

1try { 2 3//接続 4$dsn = "dbname=aaaa;host=localhost"; 5$user = "root"; 6$password = ""; 7$dbh = new PDO($dsn, $user, $password); 8$dbh->query("set names utf8"); 9 10print "接続しました。"; 11//接続解除 12$dbh = null; 13 14} catch(exception $e) { 15 print "ただいま障害が発生しており大変ご迷惑おかけしております。".mb_convert_encoding($e->getMessage(),'UTF-8','JIS,ASCII,CP51932,SJIS-win'); 16 exit(); 17} 18

たまたまネットサーフィンしているときに、データベースに接続する際のことを指南しているサイトを見つけ閲覧していたところ下記のソースが記述してありました。

php

1try { 2 $pdo = new PDO('mysql:dbname=phpdb;host=127.0.0.1', 'root', '1234', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)); 3 $pdo->query('SET NAMES utf8'); 4 5 $stmt = $pdo->query('SELECT * FROM address WHERE no >= 10 AND no <= 20'); 6 while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) { 7 echo '<p>' . $data['no'] . ':' . $data['name'] . "</p>\n"; 8 } 9} catch (PDOException $e) { 10 exit($e->getMessage()); 11} 12 13$pdo = null;

http://www.php-labo.net/tutorial/class/pdo.html

PDOの第4引数に何かを指定できること自体、ネットサーフィンをして初めて知りました。第4引数にDB接続中に発生したエラーをどのように通知するかを指定できるATTR_ERRMODEとERRMODE_EXCEPTIONを指定することで
"接続時"以外のエラーが発生したときも一律に例外を投げることが出来るのでソースの記述が短くなります。
ここで疑問ですが、先述の技巧と接続時のエラーのみ例外を投げ、それ以外は、条件分岐などで個別にエラーの対処をするのは、どちらが適当であると思いますか。
ソースが短くなる以外に、何か利点はありますか。

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

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

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

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

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

guest

回答1

0

ベストアンサー

お邪魔します。

難しい問題ですね。意見の分かれるところだと思いますが。

説明のために、異常が発生するケースを分類してみましょう。
異常が発生するケース、というのは大まかに言って

  1. ハードの異常やネットワーク異常など、アプリケーションでは回復不能なエラー
  2. コーディングミスや設計ミスによる不具合(アサーション例外を含める)
  3. 処理の順序や仕様上想定されない操作によって発生する回復可能な例外

このくらいに分類できるのではないか、と思います。

例外というのは何かしらアプリケーションに起きている問題を、開発者やユーザに知らせるための機構であると考えることができます。
アプリケーションの動作のしようがないからアプリケーションを落としてしまうとか、次に登録ボタンを押したときは大丈夫かもしれないから放置で知らんぷりとか、そういうのは設計としてお粗末ですよね。
ロギングを行って異常を回復するための情報を保守開発者に対して残す(ロギングをトリガにメールが飛ぶ機構などもよくありますね)、ユーザに異常を伝えてシステムの管理者や保守を行っている人間に連絡を取るよう促す(=ようするにメッセージの表示、ということになるのかな)、など誰かに異常発生を伝えるためのトリガとなるイベントなんです。

そう考えると異常発生時の挙動の設計がまずあるべきで、1.ならこのエラーはユーザに伝えても仕方がないなとか、いやこれはシステムダウンしてるしエラーページ表示しないとなとか、3.なら先にこのページを開いてこの操作をしてもらわないといけないからユーザにメッセージを表示しようとか、それぞれ例外が発生する状況で要求される動作が自然と決まっていくはずです。

異常を誰にどう伝えるかが決まると、異常発生を捕捉し対応するログ出力やメッセージの表示やページ遷移の処理を記述する必要が出てきます。例外の種類(=異常の原因)によって行うべき処理が異なってくると、一つのcatch節でより抽象的な例外をハンドリングしてコーディングするのはあまり格好が良くなく、どのコードが原因で異常が発生したのかをとらえにくくなってしまいます。

少し話はずれますが、避けることができる例外を発生させる、処理の実現方法として例外を使用するやり方は、混乱を招くのでよくない、とされています。
賛否両論ありますが、先にテーブルのデータを調べておけば発生しない例外、例えばUPDATEするレコードがない時でもあえて一度UPDATEをかけて例外が発生したらインサートに切り替える、などという書き方もありますが、更新を実行して失敗するという無駄な処理(データベース上でもトランザクションが発生し、行やテーブルのロックも起こるでしょう)が実行され、その分処理が遅くなったり、処理によってはデッドロックの危険性を高めたりもするので、先にSELECTをかけてから結果をみてUPDATEをかけるかINSERTをかけるか判断する、といった実装をすることが多いです。(DBサーバ因ってはmergeなんてのがあらかじめ用意されてたりもしますが)

また、2.のアサーション例外はハンドリングするべきでない、というかテストで出ないように潰すべきものですね。バグの原因の特定がしやすいように例外にメッセージを出すのが良いやり方です。例外で落ちると、直さないといけないことがわかりやすくていいです。
デバッグ起動以外では投げられないようにしておくのも、少し黒いですが現実的な考えですね。

少し質問の内容とはズレたところがあったかもしれませんが、例外処理・エラーハンドリングに対する全般的な考え方について思うところを記載してみました。

長々と書きましたが、結論としては、すべて一か所でハンドリングするかそうでないかは、想定される異常と、それぞれの異常発生時にどのような回復処理や通知処理を行うか、また、その処理でどれだけの処理をするか(=SQLを実行するか)、という設計による、というのが回答です。

以上です、参考になりましたら幸いです。

追伸

自分は本職がjava書きなもので、java言語だと例外処理についてこういう議論がなされてるよ、という参考リンクを張っておきます。質問の内容からするとぐっと深いところですが、例外マスターになれるかも?!
参考まで。
Java のチェック例外と非チェック例外の考察まとめ

投稿2016/07/05 15:28

ShinpeiYamamoto

総合スコア540

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問