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()メソッドがありますので、簡単に特定ビューとレスポンスコードを持ったレスポンスオブジェクトをリターンできます。
後は、お好みに合わせて、ご自由にどうぞ。