m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

cakephp3でエラー画面

エラー画面を多少はカスタマイズしたい…

エラー内容自体はともかく、デフォルトのフォーマットはマズイし…

環境

CentOS7.x
php7.0.3
cakephp3.2.3

実装

エラー用コントローラーを作成

src/Controller/AppErrorController.php

<?php

namespace App\Controller;

use Cake\Controller\ErrorController;
use Cake\Event\Event;

/**
 * 独自のエラーコントローラー
 * Class AppErrorController
 * @package App\Controller
 */
class AppErrorController extends ErrorController
{
    /**
     * 描画前処理
     *
     * @param Event $event
     */
    public function beforeRender(Event $event)
    {
        // エラーの共通レイアウト名を指定
        // src/Template/Layout/error_layout.ctp
        $this->viewBuilder()->layout('error_layout');

        // エラーテンプレートパスを指定
        $this->viewBuilder()->templatePath('Error');
    }
}

※描画前にテンプレートパスやレイアウトを指定する

レンダラーを作成

src/Error/AppExceptionRenderer.php

<?php
namespace App\Error;

use Cake\Error\ExceptionRenderer;
use Exception;
use Cake\Log\Log;
use App\Controller\AppErrorController;

/**
 * 独自例外用レンダラー
 *
 * Class AppExceptionRenderer
 * @package App\Error
 */
class AppExceptionRenderer extends ExceptionRenderer
{

    /**
     * 独自のコントローラーを指定
     * @param Exception $exception
     * @return AppErrorController
     */
    protected function _getController()
    {
        // 独自のコントローラーを指定
        return new AppErrorController();
    }

    /**
     * 独自のテンプレート名を指定
     *
     * @param Exception $exception
     * @param string $method
     * @param int $code
     * @return string
     */
    protected function _template(Exception $exception, $method, $code)
    {
        // src/Template/Error/error_custom.ctp
        return $this->template = "error_custom";
    }
}

※テンプレートを指定

設定ファイルを編集

config/app.php

<?php
return [
    'Error' => [
        'errorLevel' => E_ALL & ~E_DEPRECATED,
        //'exceptionRenderer' => 'Cake\Error\ExceptionRenderer',
        'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
        'skipLog' => [],
        'log' => true,
        'trace' => true,
    ],

※レンダラーを変更

エラー用レイアウトを作成

src/Template/Layout/error_layout.ctp

<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <?= $this->fetch('title') ?>
    </title>
    <?= $this->Html->meta('icon') ?>
    <?= $this->fetch('meta') ?>

    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/app.css">
    <?= $this->fetch('css') ?>

</head>
<body>
    <header id="header">
        <nav class="navbar navbar-default">
            <div class="container">
                <a class="navbar-brand" id="logo" href="/">
                    CakePHP3 Demo
                </a>
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class="nav navbar-nav navbar-right hidden-sm">
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-12">
                <div style="">
                    <?= $this->Flash->render() ?>
                </div>
            </div>
        </div>
    </div>
    <div class="container-fluid">
        <?= $this->fetch('content') ?>
    </div>
    <footer>
    </footer>
    <script src="/js/jquery-2.2.1.min.js"></script>
    <script src="/bootstrap/js/bootstrap.min.js"></script>
    <?= $this->fetch('script') ?>
</body>
</html>

エラー用テンプレートを作成
<?php
use Cake\Core\Configure;
use Cake\Error\Debugger;
?>
<div class="row">
    <div class="col-md-12">
        <div style="width: 800px;margin: 0 auto;">
            <h2><?= __d('cake', 'An Internal Error Has Occurred') ?></h2>
            <p class="error">
                <strong><?= __d('cake', 'Error') ?>: </strong>
                <?= h($message) ?>
            </p>
            <?php if (!empty($error->queryString)) : ?>
                <p class="notice">
                    <strong>SQL Query: </strong>
                    <?= h($error->queryString) ?>
                </p>
            <?php endif; ?>
            <?php if (!empty($error->params)) : ?>
                    <strong>SQL Query Params: </strong>
                    <?= Debugger::dump($error->params) ?>
            <?php endif; ?>
            <?php if ($error instanceof Error) : ?>
                    <strong>Error in: </strong>
                    <?= sprintf('%s, line %s', str_replace(ROOT, 'ROOT', $error->getFile()), $error->getLine()) ?>
            <?php endif; ?>
            <?php
                echo $this->element('auto_table_warning');

                if (extension_loaded('xdebug')):
                    xdebug_print_function_stack();
                endif;

                $this->end();
            ?>

        </div>
    </div>
</div>

画面

f:id:m_shige1979:20160308004400p:plain
スタックトレースはおいおい対応する

所感

エラー画面って難しいと思います。よくわからないのでログ吐きまくって調べてしまった。
まだおかしい部分があるのですか今回はこれでなんとかする。