エラーと例外処理
cakePHPでは、エラー処理と例外処理が用意されている。PHPエラーはトラップされ、表示またはログに記録される。キャッチされなかった例外はエラーページに自動的にレンダリングされる。
例外処理の設定
例外処理の設定はconfig/app.phpで行われる。デフォルトではCake\Error\ErrorHandlerを使う。
例外処理のカスタマイズ
例外の処理方法を調整するいくつかの方法が用意されている。
エラーテンプレートのカスタマイズ
エラーページのビューはApp/Template/Errorに配置される。
すべての 4xx エラーは error400.ctp テンプレートを使い、 すべての 5xx エラーは error500.ctp を使う。
エラーテンプレートの変数は次の通り。
- message: 例外メッセージ
- code: 例外コード
- url: リクエストURL
- error: 例外オブジェクト
<?php // src/Template/Error/error400.ctp の中で $this->layout = 'my_error'; ?>
上記は、エラーページのレイアウトとして src/Template/Layout/my_error.ctp を使用する。
ErrorControllerのカスタマイズ
App\Controller\ErrorController クラスは CakePHP の例外レンダリングでエラーページビューを 描画するために使われ、すべての標準リクエストライフサイクルイベントを受け取る。
<?php namespace App\Controller\Admin; use App\Controller\AppController; use Cake\Event\EventInterface; class ErrorController extends AppController { /** * Initialization hook method. * * @return void */ public function initialize(): void { $this->loadComponent('RequestHandler'); } /** * beforeRender callback. * * @param \Cake\Event\EventInterface $event Event. * @return void */ public function beforeRender(EventInterface $event) { $this->viewBuilder()->setTemplatePath('Error'); } } ?>
どのコンポーネントが使用され、どのテンプレートが描画されるかを制御する。
独自アプリケーション例外の作成
組み込みの SPL の例外 、 Exception そのもの、または Cake\Core\Exception\Exception のいずれかを使って、独自のアプリケーション例外を作ることができる。
<?php use Cake\Core\Exception\Exception; class MissingWidgetException extends Exception { // コンテキストデータはこのフォーマット文字列に差し込まれます。 protected $_messageTemplate = '%s が見当たらないようです。'; // デフォルトの例外コードも設定できます。 protected $_defaultCode = 404; } throw new MissingWidgetException(['widget' => 'Pointy']); ?>
上記の例ではMissingWidgetExceptionという例外を作成している。このときテンプレートはsrc/Template/Error/missing_widget.ctpになる。
ExceptionRendererのカスタマイズ
アプリケーション固有の例外クラスに対してカスタムエラーページを提供する。カスタム例外レンダラークラスは src/Error に配置する。
<?php // src/Error/AppExceptionRenderer.php の中で namespace App\Error; use Cake\Error\ExceptionRenderer; class AppExceptionRenderer extends ExceptionRenderer { public function missingWidget($error) { $response = $this->controller->response; return $response->withStringBody('おっとウィジェットが見つからない!'); } } ?>
// config/app.php の中で 'Error' => [ 'exceptionRenderer' => 'App\Error\AppExceptionRenderer', // ... ], // ... ?>
上記の例では、カスタム例外レンダラークラスの中でMissingWidgetExceptionに対して missingWidgetというメソッドを作成している。
cakePHP用の組み込みの例外
- Cake\Http\Exception\BadRequestException: 400 Bad Request
- Cake\Http\Exception\UnauthorizedException: 401 Unauthorized
- Cake\Http\Exception\ForbiddenException: 403 Forbidden
- Cake\Http\Exception\InvalidCsrfTokenException: (無効なCSRFトークンによる)403 Forbidden
- Cake\Http\Exception\NotFoundException: 404 Not Found
- Cake\Http\Exception\MethodNotAllowedException: 405 Method Not Allowed
- Cake\Http\Exception\NotAcceptableException: 406 Not Acceptable
- Cake\Http\Exception\NotAcceptableException: 406 Not Acceptable
- Cake\Http\Exception\ConflictException: 409 Conflict
- Cake\Http\Exception\GoneException: 410 Gone
- Cake\Http\Exception\InternalErrorException: 500 Internal Server Error
- Cake\Http\Exception\NotImplementedException: 501 Not Implemented
- Cake\Http\Exception\ServiceUnavailableException: 503 Service Unavailable などなど
<?php use Cake\Http\Exception\NotFoundException; public function view($id = null) { $article = $this->Articles->findById($id)->first(); if (empty($article)) { throw new NotFoundException(__('記事が見つかりません')); } $this->set('article', $article); $this->set('_serialize', ['article']); } ?>