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

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

ただいまの
回答率

90.48%

  • PHP

    20880questions

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

  • CakePHP

    2362questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

cakephpでの例外処理(try catch)の書き方を教えてください。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,351

amakusa

score 168

皆さんお疲れ様です。
先日から何度もcakephp関連の質問に対して丁寧にお答えしていただきありがとうございます。
今回はすごく具体的なことをお聞きします。
質問が長くなり、見えにくいかとは思いますがご容赦ください。
私のcakephpはversion2.6.4です。

今現在、cakephpにtry catch文を用いて例外処理をしようとしています。
しかし、正直まだ例外処理をどこに書いたらよいのかもあまり理解できておりません。
バリデーションは書いていますが、これでよいのかさえ正直わかりません。
目星として、データを扱うcontroller内に書けばよいのかなとあたりをつけています。

以下コードです。

public function index() {

      //Reportコレクションに対するバリデーション--------------------------------------
      $this->Report->set($this->request->data);
      if ($this->Report->validates()) {
          //正しい場合のロジック
      } else {
          //正しくない場合のロジック
          $errors = $this->Report->validationErrors;
      }

      //Requestコレクションに対するバリデーション-------------------------------------
      $this->Request->set($this->request->data);
      if ($this->Request->validates()) {
          //正しい場合のロジック
      } else {
          //正しくない場合のロジック
          $errors = $this->Request->validationErrors;
      }

     //queryのidを元にreportのオブジェクトを取得-------------------------------------
     $reportId = $this->request->query['id'];

     $report = $this->Report->find('all', array('conditions' => array("id" => $reportId)));//そのreportsの中にあるさっきのidがあるドキュメントの情報を取得
     $report_obj = $report[0]["Report"];

     //ReportsCollectionから変数をセット-------------------------------------------
     $userid = $report_obj["userObjectId"];
     $requestId = $report_obj["requestId"];
     $reason = $report_obj["reason"];
     $message = htmlspecialchars($report_obj["message"]);
     $comment = $report_obj["comment"];
     $reportstatus = $report_obj["status"];
     $modified = $report_obj["modified"]->toDateTime()->format('Y-m-d H:i:s');
     $created = $report_obj["created"]->toDateTime()->format('Y-m-d H:i:s');

     //report_objのrequestIdから該当するオブジェクトを取得----------------------------
     $request = $this->Request->find('all', array('conditions' => array("id" => $requestId)));//先ほどのrequestIdがあるrequestsの中のドキュメントを取得
     $request_obj = $request[0]["Request"];

     //RequestsCollectionから変数をセット------------------------------------------
     $imagepath = $request_obj["imagePath"];
     $requeststatus = $request_obj["status"];

     //ビューに変数を引き渡す-------------------------------------------------------
     $this->set(compact("reportId", "userid", "requestId", "reason", "message", "comment", "reportstatus", "modified", "created", "imagepath", "requeststatus"));
     $this->set('imagehost', IMAGEPATH);
  }

このpublic function indexでは主に変数を決めてviewに渡しているだけなので、バリデーションしか書いておりません。もしここでも例外処理を書く必要があればどこにどう書けばよいのか教えていただきたいです。

次はpublic function updateです

 public function update(){

      //Reportコレクションに対するバリデーション--------------------------------------
      $this->Report->set($this->request->data);
      if ($this->Report->validates()) {
          //正しい場合のロジック
      } else {
          //正しくない場合のロジック
          $errors = $this->Report->validationErrors;
      }

      //Requestコレクションに対するバリデーション-------------------------------------
      $this->Request->set($this->request->data);
      if ($this->Request->validates()) {
          //正しい場合のロジック
      } else {
          //正しくない場合のロジック
          $errors = $this->Request->validationErrors;
      }

     $this->autoRender = false;
     //処理状態の更新--------------------------------------------------------------

     if(isset($this->request->data['report_status'])){
        $reportId = $this->request->data['report_id'];
        $report = $this->Report->find('all', array('conditions' => array("id" => $reportId)));//そのreportsの中にあるさっきのidがあるドキュメントの情報を取得
        $report_obj = $report[0]["Report"];
        $report_obj["status"] = $this->request->data['report_status'];
        $report_obj["modified"] = array('modified' => date('Y-m-d H:i:s'));
        $data = $report_obj;
        $this->Report->save($data);

        $this->redirect($_SERVER['HTTP_REFERER']);
     }
     //表示状態の更新--------------------------------------------------------------

     if(isset($this->request->data['request_status'])){
         $requestId = $this->request->data['request_id'];
         $request = $this->Request->find('all', array('conditions' => array("id" => $requestId)));//そのreportsの中にあるさっきのidがあるドキュメントの情報を取得
         $request_obj = $request[0]["Request"];
         $request_obj["status"] = $this->request->data['request_status'];
         $data = $request_obj;
         $this->Request->save($data);

         $reportId = $this->request->data['report_id'];
         $report = $this->Report->find('all', array('conditions' => array("id" => $reportId)));//そのreportsの中にあるさっきのidがあるドキュメントの情報を取得
         $report_obj = $report[0]["Report"];
         $report_obj["modified"] = array('modified' => date('Y-m-d H:i:s'));
         $data = $report_obj;
         $this->Report->save($data);

         $this->redirect($_SERVER['HTTP_REFERER']);
     }
     //コメントの更新--------------------------------------------------------------

     if(isset($this->request->data['report_comment'])){
         $reportId = $this->request->data['report_id'];
         $report = $this->Report->find('all', array('conditions' => array("id" => $reportId)));//そのreportsの中にあるさっきのidがあるドキュメントの情報を取得
         $report_obj = $report[0]["Report"];
         $report_obj["comment"] = $this->request->data['report_comment'];
         $report_obj["modified"] = array('modified' => date('Y-m-d H:i:s'));
         $data = $report_obj;
         $this->Report->save($data);

         $this->redirect($_SERVER['HTTP_REFERER']);
     }
  }

こちらではDBのフィールド3つに対してpostしています。
saveがあるのでこの部分に例外処理を書かなければいけないだろうとは思うのですが、
function自体に対して例外処理をかけるのか、それとも$this->Report->save();のところだけにかけるのかを教えていただきたいです。

1つとっかかりがわかればだいたいできると思うのですがとっかかりすらない状態なのでなんとか教えていただきたいです。宜しくお願い致します。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+3

$this->Request->save(); この行の結果が失敗だった場合falseが返りますので、
以下の通りで大丈夫です。
if ($this->Request->save(....) === false) {
  //エラーメッセージやその後の処理
}
try catch を使う必要はないかと思います。

例外処理とは関係ありませんが、$this->Request->save() の第3引数にフィールドリストを指定することをお勧めします。

try catch の必要性が最初から分かっている箇所では、それを未然に防ぐコードを書くべきです。例えばゼロでの除算が発生しうる箇所では除算前にゼロか否かの判断をして適切な分岐を行います。
と、私は考えます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/06 01:47

    回答ありがとうございます!
    では、他の箇所でのtry catch文は必要ない、ということでしょうか?
    DBからgetでdataを持ってきたりするときには必要なくて、postでdataを送るときのみ例外処理は必要になる、という認識でよろしいのでしょうか?
    質問ばかりですみませんがお願い致します。

    キャンセル

  • 2015/08/06 08:32

    phpの場合は例外を投げる(throw)することによりcatchできますので、これは事前のif文などの分岐で対応できます。勝手にthrowされることは有りません。
    他のコンパイラ言語の場合は自動的にthrowされる仕様の言語が有りますのでtry catch を書けばエラーを捕獲してくれます。
    と思いますがこのあたりの回答は自信がありません。
    と言いますのは、
    私はtry catch で処理するよりは想定されるエラーが有るなら条件分岐でエラーを回避するべきと考えており、極力try catchを使わないようにしているからです。
    phpではtry catchをほぼ使ったことが有りません。
    例外を未然に防ぐコードを書く事により、フローが明確になりますし、デバッグ意識が高まります。
    VB.NET等のコンパイラ言語ではそれなりにtry catchを使用します。
    これは書き方に個人差があると思います。
    逆に皆様にphpでtry catchを使用するか否か聞いてみたいですね。

    キャンセル

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    20880questions

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

  • CakePHP

    2362questions

    CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。