- ベストアンサー
try~catch構文は、どういうメリットがあるのですか?
以下は 関数 hoge に失敗したら、例外を補足するコードです。 try { if (!hoge()) { throw new Exception('hogeに失敗しました'); } } catch (Exception $e) { echo $e; } 以下のように書いたほうが分かりやすいと思いますが、 駄目なんでしょうか? hoge() || die('hogeに失敗しました'); ちなみに、DBのトランザクションを利用して、何かに失敗したら、 catch 以下でロールバックするのは便利だと思います。 しかし、こういう場合以外で、try~catch構文を使うメリットは何でしょう?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
set_error_handler, set_exception_handlerあたりでは?
その他の回答 (3)
- _chihiro_
- ベストアンサー率63% (26/41)
No2さんのおっしゃる通り、質問者さんのソースはPHP5~で動作します。 で、try-catchのメリットですが、例えば ・throwされる例外の種類によって、対処処理を変えることができる ・一連の処理の中で、エラーが発生する箇所がいくつかある場合に、tryで囲ってまとめることができる ・オブジェクト指向な書き方ができる など、たくさんあるかと思います。 or die();の書き方だと、メッセージを表示して終了しかできませんよね。 手元で動かすような軽いスクリプトを作成するのであれば、そのような記述で良いかと思います(楽なので)が、それなりのプログラムを書く場合などは、プログラム内にor die();が数多くあると不恰好になります。 PHPはJavaのように多種の例外クラスが用意されていないので、例外クラスを自作して(FileIOExceptionとかDBExceptionなど)試してみると、そのメリットを感じやすくなると思います。
補足
>or die();の書き方だと、メッセージを表示して終了しかできませんよね。 ANo.2の補足にも書きましたが、実は、or die を使いたい訳ではありません。or die も catch も trigger_errorも極力使わずに、エラーが発生したらエラーハンドラに渡したいのです。 なんとなく気づいているのですが、きっと、わたしが作ってる物の規模が小さいから、こういう発想になっちゃうでしょうね・・・。
ん? 一応、PHPにもtry ~ catch構文はありますから、質問者さんの書かれたコードはすべてPHPとして間違いではないです。ちゃんと機能しますよ。 が、これが動くのはPHP5からです。PHP5から、特にオブジェクト指向関係でかなりの強化が図られていることはご存知でしょう。tryも、よりオブジェクティブに例外処理行えるようにするために追加されたものといえます。 or die ~ってのは、昔の「関数」を中心とした構造化の考え方ですよね。エラーが起きたらこっちを実行する、と。けれどtryによる例外処理は、エラーの発生を「例外オブジェクトの発生」という形でとらえたものです。考え方がまったく異なるのです。だから、or dieは旧来のやり方、try catchはPHP5によるオブジェクト指向にそったやり方、といってもいいんじゃないかと。 or dieだと、その直前の関数についてのみエラー処理をすることしかできませんね。例えば、ネットワークだのファイルアクセスだのになると、複数の関数が異なる例外を発生させる可能性もあります。こうしたときに、例外が発生する処理全体を一つのtryでまとめ、それぞれの例外の内容に応じて対応できるtry catchは、慣れてくるとかなり快適ですよ。(こっちがもともとJavaグラマだからってのもあるけど)
補足
Javaプログラマなら、or die ~に嫌悪感を感じるのは仕方ないかもしれません。 実は私も同じです。メインルーチンを or die で汚したくありません。 かといって、throw が連発し、try、catchが幾重にもネストするのもどうかと思うのです。 ただ実際には、throw するのはクラスの中でやるんですよね? ただここで疑問があります。PHPなら、or die としなくても、エラーが発生したら、自作のエラーハンドラで任意の処理をすることができるようです。 この場合、「エラーの発生」でなく「例外オブジェクト」の発生なら、エラーではないので、エラーハンドラに渡せません。 無理矢理やるなら、catch の中で、trigger_errorしてやらないといけないですよね? これって何か無駄なような気がします。 根本的な考え方が間違っているのでしょうか?
- harutovx
- ベストアンサー率50% (11/22)
なんかPerlとJavaがごっちゃになっちゃっているようですが、その辺の理解は大丈夫ですか? 上記はJavaのコードで、下記はPerlのコードです。 以下のように書いたほうが分かりやすいと言う前に、Javaでは通常下記のコードは動きません。例外の実装が違うからです。 try~catch構文を使うメリットは数え上げられないですが、わかりやすい例では、 IOExceptionなら○○の処理をする NetworkExceptionなら○○の処理をする と例外の種類によって処理を変えることが出来るし、書き方によっては、エラー処理を一カ所にまとめて記述できるため、視認性が上がる。 などが有ります。 実際にそのようなコードを書いて、体験しないと有用性が解りづらいかと思いますが。
補足
> と例外の種類によって処理を変えることが出来るし } catch (IOException $e) { 処理; } catch (NetworkException $e) { 処理; } のようにできるということでしょうか? > 実際にそのようなコードを書いて、体験しないと有用性が解りづらいかと思いますが。 実際に以下のように使用しております。 } catch (DBException $e) { $dbh->rollBack(); die($e->getMessage()); } DBを扱ってる際に、何かしらエラーを補足した場合にロールバックするという場合に、このtry~catch構文は非常に嬉しいです。 ですが、エラーを補足した場合に単に、エラーを出力して終わるだけの場合に、try~catch構文を使用するメリットが分からないのです。
補足
ありがとうございます。 この二つを、どのように使い分けていますか? 私は、set_error_handlerで統一したいのですが、それでもthrowしてcatchしてtrigger_errorするのが良策なんでしょうか?