CakePHPのエラーページをカスタマイズする | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

404(Not Found)や500(Internal Server Error)などページが無かったり内部エラーが発生した場合や、処理の過程で発生した例外エラーなど、何か問題があったときに表示するエラーページをカスタマイズしたいという要件はよくあります。


CakePHPでは、そういったカスタムエラーページを所定の手続きにそって行えば簡単に作ることができます。



404や500エラーが発生したページのカスタマイズ


CakePHPではデフォルトでHTTPステータスコードが404や500が発生した場合に出力するテンプレートを持っています。


/path/to/cakephp/app/View/Errors

この中にあるerror400.ctpがHTTPステータスコード404が発生した場合のエラーページ、error500.ctpが500用のエラーページです。

これを好きにカスタマイズすることでオリジナルのエラーページを作ることができます。


エラーページもLayoutの影響を受けるため、エラーページ独自でのレイアウトを適用したい場合は、上記のエラーページ内で


<?php $this->layout = "error"; ?>

として、独自のLayoutを準備して適用するか、または


<?php $this->layout = FALSE; ?>

のようにして、レイアウトを適用しないようにしておきましょう。


また、エラーページは開発環境(設定ファイル(Config/core.php)でdebugを1以上に設定)の場合、これ以外に細かなエラー画面が用意されています。

例えば、存在しないコントローラーにアクセスした場合にMissing Controllerという例外が発生するのですが、その例外エラー用に下記のようなエラーページが用意されています。


A Day In The Boy&#39;s Life-cakephp-missing_controller


これをカスタマイズしたい場合、メッセージにあるようにErrorsディレクトリ内に独自のmissing_controller.ctpを用意しておきます。


ただし、本番環境(debugを0に設定)の場合は、これらの例外エラーは全てerror400.ctpまたはerror500.ctpにまとめられます

ですので、開発環境で細かくエラー内容をトレースしたいという場合は個別にエラー画面を用意しておけばよいですが、本番環境の場合はこの2つのエラーページを準備しておくだけでよいわけです。



例外をコントロールする


このようにエラーページはCakePHPの内部で例外が発生したときに呼び出されるわけですが、その例外はCakePHP任せでなく、独自にコントロールすることも可能です。


if (!empty($fuga)) {
// 通常の処理
} else {
// 404用の例外処理を投げる
    throw new NotFoundException();
}

上記のように必要なパラメータが無ければ404用の例外を投げ、それを受けてerror400.ctpが呼び出されて出力させるということができます。

500エラーの例外を投げたければ


throw new InternalErrorException();

と書けば例外を受けてerror500.ctpが呼び出されます。


最後に、独自の例外処理を作る方法ですが、例えば変数が見つからなかった場合に呼び出すMissingVarExceptionという例外を作ってみます。

例外クラスは、CakeExceptionのサブクラスとして以下のような内容のものを用意します。


<?php
class MissingVarException extends CakeException {
    protected $_messageTemplate = '%s が見つかりません。';
}

これを、app/Libディレクトリ以下にMissingVarException.phpとして保存します。

後は、Controller側でこの例外クラスをロードするのと、利用する処理のところで適宜呼び出します。


<?php
App::uses('MissingVarException', 'Lib');

class FugaController extends AppController {
    public function index() {
        if (!empty($fuga)) {
// 通常の処理
        } else {
            throw new MissingVarException(array('var' => 'fugafuga'));
        }
    }
}

実際に例外を発生させて見るとログファイルには


2013-07-28 01:55:15 Error: [MissingVarException] fugafuga が見つかりません。

のようなエラーメッセージが出力されます。


例外のコントロール方法の詳細は、マニュアル の方も参照してみてください。