CakePHP3を使っている人ならば誰もが頭を悩ませる鬼門、「エラーページのカスタマイズ方法」を解説します!
この方法を使えば、CakePHPのデフォルトの殺風景なエラーページでなくて、オリジナルのかわいい&かっこいいエラーページを表示させることができます!
ちなみにもっと基本的なCakePHP3の使い方を知りたい人は、私の以前書いた記事「CakePHP3超入門!Hello Worldを表示するゾ!」をご参照ください・・。
(※本ブログで使ってるCakePHPのバージョンは「3.1.13」です)
目次
「簡単なエラーページの作り方!」
まずは「簡単なエラーページの作り方」を紹介します。シンプルな構成のサイトならば、この方法で十分なはずです・・。
「テンプレートファイルの作成!」
まずはオリジナルのテンプレートファイルを作ります。
「src/Template/Error/」のディレクトリ配下に「error400.ctp」と「error500.ctp」という二つのTemplateファイルがありますよね?(もしなかったら作ってください・・)
この二つのファイルが、エラー時に表示される「画面テンプレート」です。この中身を自分の表示させたい内容に変更しましょう。
CakePHP3の「デバッグモード」をオフにしていると、全てのエラーが「400番台」と「500番台」のコードに集約されます。そしてエラー発生時には自動的にこの二つのファイルが参照されます。
(※デバッグモードをオフにするには「config/app.php」の「debug」のパラメータにfalseをセットしてください)
「レイアウトファイルの作成!」
次にオリジナルのレイアウトファイルを作ります。
「src/Template/Error/」のディレクトリ配下に、新しくLayoutファイルを作りましょう(例えば「my_err.ctp」みたいな名前のファイルです)。このファイルが、エラー時に表示される「画面レイアウト」です。
「レイアウトファイルを参照する!」
自分で作った「Layoutファイル」を参照するためには、先ほど編集した「error400.ctp」と「error500.ctp」の先頭に、「<?php $this->layout = ‘my_error’; ?>」と書き込みましょう。これで自分で作った「my_error.ctp」のレイアウトが、エラー画面に反映されるはずです。
(もしこの設定をしなかったら「src/Template/Layout/default.ctp」のレイアウトが自動的に適用されます)
以上の方法が「CakePHP公式」でも紹介されている、代表的なエラー画面のカスタマイズ方法です!
「高機能なエラーページの作り方!」
上記の「簡単なエラーページの作り方」だといろいろ不便なところがあります。例えばエラー画面を「PCとモバイル」で切り替えたいときなどは、この方法だとたぶん難しいと思います。
なのでもっと複雑なことをしたい人は、以下の「高機能なエラーページの作り方」を試してください!
「コンフィグの修正!」
「config/app.php」の中にある、エラー画面の「レンダリング設定」を変更します。デフォルトの設定の「Cake\Error\ExceptionRenderer」をやめて、自分のオリジナル設定「App\Error\AppExceptionRenderer」を反映します。
1 2 3 4 5 6 7 8 |
'Error' => [ 'errorLevel' => E_ALL & ~E_DEPRECATED, //'exceptionRenderer' => 'Cake\Error\ExceptionRenderer', 'exceptionRenderer' => 'App\Error\AppExceptionRenderer', 'skipLog' => [], 'log' => true, 'trace' => true, ], |
「レンダラーの作成!」
「/src/Error/」のディレクトリの下に、自分のオリジナルのレンダラーファイル「AppExceptionRenderer.php」を作ります(もしディレクトリがなかったら自分で掘って作ってください・・)
このレンダラーファイルによって、エラーページで使うレイアウトやテンプレートを指定することができます。
「AppExceptionRenderer.php」の内容は以下のようなものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?php namespace App\Error; use Cake\Error\ExceptionRenderer; use Exception; use Cake\Log\Log; use App\Error\AppErrorController; class AppExceptionRenderer extends ExceptionRenderer { protected function _getController() { //オリジナルのエラーコントローラーを指定 return new AppErrorController(); } protected function _template(Exception $exception, $method, $code) { //PC用とモバイル用のTemplateを切り替える //「src/Template/Error/」の下にあるTemplateファイルを参照している if($this->controller->request->is('mobile')){ $template = 'error500_mobile'; if ($code < 500) { $template = 'error400_mobile'; } }else{ $template = 'error500'; if ($code < 500) { $template = 'error400'; } } return $this->template = $template; } } |
「エラーコントローラーの作成!」
「/src/Error/」のディレクトリの下に、自分のオリジナルのエラーコントローラー「AppErrorController.php」を作ります。
このエラーコントローラーに「PCとモバイルの判定」といった複雑な処理を任せることができます。
「AppErrorController.php」の内容は以下のようなものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php namespace App\Error; use Cake\Controller\ErrorController; use Cake\Event\Event; class AppErrorController extends ErrorController { public function beforeRender(Event $event) { //PC用とモバイル用のLayoutを切り替える //「src/Template/Layout/」の下にあるLayoutファイルを参照している if($this->request->is('mobile')){ $this->viewBuilder()->layout('mobile'); }else{ $this->viewBuilder()->layout('normal'); } //Templateファイルのあるパスを指定(src/Template/Error/) $this->viewBuilder()->templatePath('Error'); } } |
「レイアウトとテンプレートの作成!」
まず、「src/Template/Layout」のディレクトリの下に、2つのLayoutファイル「normal.ctp」「mobile.ctp」を作ります。それぞれ「PC用のエラー画面」と「モバイル用のエラー画面」を表示するためのレイアウトです。
また、「src/Template/Error/」のディレクトリの下に、4つのTemplateファイル「error400.ctp」「error500.ctp」「error400_mobile.ctp」「error500_mobile.ctp」を作ります。それぞれ「PC用のエラー画面」と「モバイル用のエラー画面」を表示するためのテンプレートです。
***
ここで注意事項なんですが、上記の設定をするとレイアウトファイルの中のHTMLヘルパー(「$this->Html->css()」とか「$this->Html->js()」とか)の指し示すディレクトリがなんだか変になってしまいます・・。
私は「サブディレクトリ」でサイトを運営してるんですが、HTMLヘルパーのディレクトリが「トップドメイン」を指し示してしまって、cssやjsファイルが読み込めなくなってしまいました・・。
仕方がないので私はHTMLヘルパーを使わないで、cssやjsを全部「ベタ書き」で書くことで対処しました。
私はなにかwebrootを設定する処理を書き忘れてしまっているんでしょうかね・・?もし対処方法がわかる人がいたら、おしえてください・・。
***
以上の設定をすれば、「PC用」と「モバイル用」の別々のエラー画面が表示されるはずです。こんなめんどくさいことをしなくちゃいけないなんて、エラー画面を作るのってとっても大変なんですね・・。CakePHP3はもっと簡単な方法を用意してほしいものです・・。