Cakephp 3 - var not transmitted to view when exception thrown

夙愿已清 提交于 2020-01-15 13:34:06

问题


In my AppController, I define a variable that must be used in every views (including error400.ctp, error500.ctp) of my app:

// /src/Controller/AppController.php
public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);
    $foo = 'bar';
    $this->set(compact('foo'));
}

It works well, except when an exception is thrown (like NotFoundException): I get the following error:

Undefined variable: foo in /src/Template/Error/error400.ctp

Is this a normal behavior of cakephp? How could I fix this?


回答1:


Yes, this is normal behaviour, what is basically happening:

  1. Exception is thrown (beforeFilter was called depending on where was it thrown, e.g. it is called for MissingAction or MissingTemplate, but not for MissingController).

  2. Request handling is aborted and ErrorHandler steps in to catch and handle that Exception.

  3. To render the Exception, ErroHandler uses ExceptionRenderer, which in turn creates special ErrorController, that kind of replaces original controller. This also means, that now you have completely different controller handling the request (new instance of Controller class), so even if beforeFilter was called and $foo was set, it is not longer valid.

  4. ExceptionRenderer will use its own render() method to create output for error page.

To customize this, you can extend that default ExceptionRenderer, so you will be able to set variables to ErrorController

<?php
// goes in src/Error/AppExceptionRenderer
namespace App\Error;

use Cake\Error\ExceptionRenderer;

class AppExceptionRenderer extends ExceptionRenderer
{
    public function render()
    {
        $this->controller->set('foo', 'bar');
        return parent::render();
    }
}

Set this class as default ExceptionRenderer in app.php

//...
'Error' => [
    // ...
    'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
    // ...
],

So you need to set that global view variable in two places. Use some common method from models, Configure class to read global variables or whatever is suitable for your requirements.

More on custom error handling: Extending and Implementing your own Exception Handlers



来源:https://stackoverflow.com/questions/30315153/cakephp-3-var-not-transmitted-to-view-when-exception-thrown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!