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

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

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

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

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

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

Q&A

解決済

2回答

1558閲覧

PHP Laravel5.5の例外処理共通化 グローバル参照

byth_net

総合スコア12

Laravel

LaravelとはTaylor Otwellによって開発された、オープンソースなPHPフレームワークです。Laravelはシンプルで表現的なシンタックスを持ち合わせており、ウェブアプリケーション開発の手助けをしてくれます。

PHP

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

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

Laravel 5

Laravel 5は、PHPフレームワークLaravelの最新バージョンで、2014年11月に発表予定です。ディレクトリ構造がが現行版より大幅に変更されるほか、メソッドインジェクションやFormRequestの利用が可能になります。

0グッド

2クリップ

投稿2019/05/24 13:35

編集2019/05/25 01:33

お世話になります。
この度、初めてLaravelを使用したWebAppを構築しております。
ある機能を作成するなかで、クラスの構成に悩んでしまい、手も足もでなくなってしまったので、相談させてください。

環境

PHP 7.3.4
Laravel 5.5

前提・実現したいこと

以下のような構成で各Controllerへ処理を振り分けています。
予期せぬExceptionの発生時、App\Exceptions\HandlerでそのExceptionをCatchし、
どの機能でエラーが発生したかのログを共通的に出力したいと考えております。
※ログはLaravel標準のログではなく、DBへ登録しています。
このような場合に、どのようなデザインにすれば良いのか、悩んでおります。

↓---------- [2019/5/25 10:30追記] ----------↓

要件が不足していたようなので、追記いたします。
ControllerからthrowするExceptionを、私の中で以下のように分類おり、それぞれ異なる動作としたいと考えています。
そもそも考え方がおかしい的なご指摘でも、助かります。

  1. 各Controllerで発生することが予測できるException

 ⇒各Controllerでcatchして、Controllerごとに処理を決定する。(画面上にエラーメッセージ表示等)

  1. 自作ExceptionA
  2. 自作ExceptionB

 ⇒各処理ではcatchせず(またはそのままthrowする)、共通動作を動かしたい。
⇒現在はApp\Exceptions\Handlerのrenderで判定し、共通動作としています。

  1. それ以外の予期せぬException

 ⇒各処理ではcatchせず(またはそのままthrowする)、共通動作を動かしたい。

上記の、2.3.4.のパターンの場合に、どのControllerで発生したExceptionか?の情報が欲しい。

↑---------- [2019/5/25 10:30追記] ----------↑

イメージ説明

私の考え

無理やりやるのであれば、セッションを使うなど思いつくのですが、適切でない気がしています。

私には、各ControllerでExceptionを独自Exceptionでラップし、その中にどの機能かの情報を付与するくらいの案しか思いつきませんでした…。

Laravel のような便利なFrameworkを使用した場合のベストプラクティスが知りたいです。お力添えいただいたけると幸いです。

ソース

HogeController.php

PHP

1class HogeController extends Controller 2{ 3 public function __construct(HogeService $service) 4 { 5 $this->service = $service; 6 $this->functionId = FunctionIdConst::HOGE; 7 } 8  : 9}

App\Exception\Handler.php

PHP

1class Handler extends ExceptionHandler 2{ 34 public function render($request, Exception $exception) 5 { 6 if ($exception instanceof MyExceptionA) { 7 // 処理A 8 } elseif ($exception instanceof MyExceptionB) { 9 // 処理B 10 } else { 11 // ★ここで、ログ出力したい。 12 } 13 } 14}

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

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

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

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

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

guest

回答2

0

https://readouble.com/laravel/5.8/ja/errors.html

App\Exceptions\Handlerにcontext()書けば発生時のURLでもコントローラーでもなんでも取得できる。

protected function context() { return array_merge(parent::context(), [ 'url' => url()->full() ?? '', 'controller' => request()->route()->getActionName() ?? '', ]); }

これを記録すればいい。

public function report(Exception $exception) { $context = self::context(); parent::report($exception); }

投稿2019/05/24 15:57

kawax

総合スコア10377

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

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

byth_net

2019/05/25 07:50

遅くなりましたが、ご教示ありがとうございます。 上記の内容について、調べてみました。 カレントのControllerのインスタンスかクラスが欲しかったのですが、簡単には取れなさそうですね。 やっぱりそもそもそんなものを取ろうとしているのがおかしいんですかね…。 全体の造りをもう少し見直す必要があると猛省しています…。
guest

0

ベストアンサー

laravel二カ月目の自分も気になったので作ってみました。

bash

1php artisan make:exception MushokuNeetException

Exception

1use Illuminate\Http\Request; 2class MushokuNeetException extends Exception 3{ 4 5 public $request; 6 public $functionName; 7 8 public function __construct(Request $request, $functionName){ 9 $this->request = $request;//なんとなく 10 $this->functionName = $functionName; 11 } 12 13 public function report(){ 14 \Log::info('Error:'.$this->functionName); 15 //ここで好き放題ログを吐いた方が良さそう 16 } 17} 18

controller

1public function shukatsu(){ 2 throw new MushokuNeetException($request, __FUNCTION__); 3}

Handler

1 public function render($request, Exception $exception) 2 { 3 if($exception instanceof MushokuNeetException){ 4 Log::error('無色ニートエクスェプション'); 5       //ここでログを吐くよりも 6 } 7 }

ラップをするためのものはartisanで作れるらしい
試しに作ったMushokuNeetExceptionではrender実装までは試してないけど、render実装すればそこで処理終わるんでしょうねきっと

投稿2019/05/24 14:36

hentaiman

総合スコア6415

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

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

byth_net

2019/05/25 00:36

回答ありがとうございます。参考になります。 Controllerで必ずExceptionをラップして渡すような動きですかね。 そのうえで、ラッパークラスにでreportメソッドを実装ですか、これはFrameworkの仕組みでどこかから呼び出されるのでしょうか?それとも自分で呼び出す必要がある…? こうなると、report側でもinstanceofで、元のExceptionの種類を判別し、ログ出力するかどうか決める必要がありそうですね。
hentaiman

2019/05/25 01:01

あなたの言うラップの意味が一般的に使われているラップならですけど、Exceptionのラッパーは回答に書いたMushokuNeetException で、これはartisanコマンドから作れます。 各Controllerから吐き出そうとしている例外の種類がすべて同じで、パラメーターだけ違うのであればどのControllerからもMushokuNeetExceptionをthrowしすればよく、その際に必要なパラメーターだけ渡す(MushokuNeetExceptionで受け取れる)ようにすればいいです。 各Controllerから吐き出そうとしている例外の種類がそれぞれ全く違うものなら、その分だけartisan makeでExceptionをラップしたカスタムExceptionを作るのが適切かなと。 >こうなると、report側でもinstanceofで、元のExceptionの種類を判別し、ログ出力するかどうか決める必要がありそうですね。 必ずログを吐かせたいのならその考え方は不適当で、カスタムExceptionを作る段階でログを吐く処理を組み込んでしまうのが適当です。 それともControllerでラップするというのは、結果に応じて処理を分けるif的な意味合いで言ってますか?
hentaiman

2019/05/25 01:11 編集

>そのうえで、ラッパークラスにでreportメソッドを実装ですか、これはFrameworkの仕組みでどこかから呼び出されるのでしょうか?それとも自分で呼び出す必要がある…? 自分で呼ぶ必要は無い
byth_net

2019/05/25 01:39

コメントへの返信ありがとうございます。 要件を追記させていただきました。 今回のケースだと、hentaimanさんのおっしゃる「各Controllerから吐き出そうとしている例外の種類がそれぞれ全く違うもの」に該当するでしょうか。 追記した4.についても、カスタムExceptionを作成し、2.3.4のカスタムExceptionクラスに、reportメソッドを実装し、ログ出力⇒それ以外の画面に返すなどの動作はrenderメソッドに組み込み …少しイメージが湧いてきました…!
hentaiman

2019/05/25 01:56

追記の要件に対して > 各Controllerで発生することが予測できるException 完全に主観で回答しますが ・フロント側に対してURLを変えずにエラー画面を表示させたい ・しかも内部的にはエラーとして扱いたい ・ログの内容は大体同じ(そしてでそれを元に後で調査したわけではない) ・さらにエラーの処理が複雑だ これらの条件が重なるならカスタムExceptionを作ればいいでしょうが、そうでないなら普通にController内でif分岐して必要に応じてログ出力とエラー画面表示用のviewをreturnすれば良いと思います。 ifが複雑になるならModelクラス作って分離すればいい。 今作ろうとしているシステムは本当に該当の処理をExceptionとして実装する必要がありますか?
byth_net

2019/05/25 07:42

> 今作ろうとしているシステムは本当に該当の処理をExceptionとして実装する必要がありますか? 確かに、そもそもExceptionとする必要はないのかもしれません。 そもそもExceptionとして扱おうと思った経緯が、App\Exceptions\Handlerのrenderで共通的に処理したかったがためなので、その考え方がまずかったのかもと思いました。 >これらの条件が重なるならカスタムExceptionを作ればいいでしょうが、そうでないなら普通にController内でif分岐して必要に応じてログ出力とエラー画面表示用のviewをreturnすれば良いと思います。 なるほど、これまで教えていただいた内容を踏まえると、以下のような形が適当だったのかもしません。  1. そのまま各Controllerで処理  2.3. そもそもExceptionにすべきではなく、異常発生時に各Controllerで処理(またはその内容を共通化する)  4. 仕方ないので、各Controllerでキャッチしでどの機能で発生したかの情報を付与し、Handlerで処理する     色々な考えを提示していただきありがとうございます。
mikkame

2019/05/26 11:16

遅レスですがMushokuNeetという命名は冗長じゃないでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問