Laravel4、カスタムエラーページ
タグ: Laravel4
自分でカスタマイズしたエラーページを表示する方法の一例の紹介です。
一番簡単なのは、app/start/global.phpの中の、例外ハンドラーを以下のように変更します。
<?php if( !Config::get( 'app.debug' ) ) { App::error( function( Exception $e, $code ) { $message = $e->getMessage() == '' ? $code.'エラーです。' : $e->getMessage(); if( File::exists( app_path().'/views/errors/'.$code.'.blade.php' ) ) { return Response::view( 'errors.'.$code, array( 'reason' => $message ), $code ); } else { Log::error($e); return Response::view( 'errors.500', array( 'reason' => $message ), '500' ); } } ); }
続いて、app/view/errosにレスポンスコードに対応するビューを用意します。500.phpもしくは500.blade.phpは必ず用意してください。
もうちょっと、丁寧な方法です。
方針
app/views下にerrorsディレクトリーを作成し、その下に"レスポンスコード.blade.php"か"レスポンスコード.php"を用意しておきます。
発生したレスポンスコードに対応するbladeファイルが存在するかチェックし、存在していなければ500.blade.phpを表示します。存在していれば、そのbladeファイルを表示します。
そのため、必ず500.blade.phpを用意しておく必要があります。
この方法は、Laravel3で採用されていた方法で、いまだに人気のある実装方法です。一度作成しておけば、処理するレスポンスコードを変更したい場合にコードの変更は必要なく、ビューファイルだけを作成/削除すれば済みます。
エラービュー
エラービューも表示に統一感を持たせるために、親のレイアウト(app/view/layout.blade.php)を使用すると仮定しましょう。titleはページタイトル、contentがコンテンツ本体のセクションです。
500.blade.php
@extends('layout') @section('title') 500 内部エラーが発生しました。 @stop @section('content') <h2>内部エラーが発生しました。</h2> <p>{{ $reason }}</p> <p>時間を置いて、お試しください。</p> <p>長時間続いている場合はお手数ですが、adimin@exmaple.comまでご連絡ください。</p> @stop
404.blade.php
@extends('layout') @section('title') 404 ページが見つかりません @stop @section('content') <h2>ページが見つかりません。</h2> <p>{{ $reason }}</p> <p>古いページは削除されている可能性があります。</p> <p>URLに間違いはありませんか?確認をお願いします。</p> @stop
その他、お好みで対応するページを作成しましょう。
例外のハンドリング
以下の内容でファイルを作成し、app/start/global.phpもしくはサービスプロバイダーなどから、読み込みます。(もしくは、先の例のようにapp/start/global.phpの例外ハンドラーを書き換えます。)
<?php if( !Config::get( 'app.debug' ) ) { // 全例外の処理(主にPHPエラー) App::error( function( Exception $e ) { Log::error($e); return Response::view( 'errors.500', array( 'reason' => '内部でエラーが発生しました。' ), '500' ); } ); // HTTPエラー App::error( function (Symfony\Component\HttpKernel\Exception\HttpException $e, $code) { $message = $e->getMessage() == '' ? $code.'エラーです。' : $e->getMessage(); if( File::exists( app_path().'/views/errors/'.$code.'.blade.php' ) ) { return Response::view( 'errors.'.$code, array( 'reason' => $message ), $code ); } else { return Response::view( 'errors.500', array( 'reason' => '内部でエラーが発生しました。' ), '500' ); } } ); }
例外ハンドラーは全般的なものから、個別のものへと順番に宣言します。HTTPエラーは2つ目のハンドラーで処理され、それ以外のエラーは全部最初のハンドラーで処理されます。
ポイントとなるのは、ルートからならViewを返しても自動的にレスポンスクラスに変換されますが、例外の処理から返せるのは、レスポンスクラスだけであることです。(この仕組みは変更されているかも知れません。)Response::view()メソッドがありますので、簡単に特定ビューとレスポンスコードを持ったレスポンスオブジェクトをリターンできます。
後は、お好みに合わせて、ご自由にどうぞ。