Cakephp 3 - 当传出异常时,var不传输到视图 [英] Cakephp 3 - var not transmitted to view when exception thrown
问题描述
public $ before $($ event)
{
parent
$ foo ='bar';
$ this-> set(compact('foo'));
}
除非抛出异常(如NotFoundException),否则它的效果很好:I得到以下错误:
未定义的变量:foo in /src/Template/Error/error400.ctp
这是cakephp的正常行为吗?如何解决这个问题?
是的,这是正常的行为,基本上发生了什么: >
-
异常被抛出(
beforeFilter
被调用,取决于它抛出的位置,例如它被称为MissingAction或MissingTemplate,但不适用于MissingController)。 -
请求处理中止,
ErrorHandler
抓住并处理该异常的步骤。 -
要渲染异常,
ErroHandler
使用ExceptionRenderer
,这又创建了特殊的ErrorController
,这种替换原始控制器。这也意味着,现在你有完全不同的控制器处理请求(Controller类的新实例),所以即使beforeFilter
被调用,$ foo
被设置,它不再有效。 -
ExceptionRenderer
将使用自己的render()
方法来创建错误页面的输出。
要自定义此项,您可以扩展该默认值 ExceptionRenderer
,以便您可以将变量设置为 ErrorController
<?php
//进入src / Error / AppExceptionRenderer
命名空间App \Error;
使用CakeElement
class AppExceptionRenderer extends ExceptionRenderer
{
public function render()
{
$ this-> controller-> set('foo' '酒吧');
return parent :: render();
}
}
将此类设置为<$ c $中的默认值ExceptionRenderer c> app.php
// ...
'Error'=> [
// ...
'exceptionRenderer'=> 'App \Error\AppExceptionRenderer',
// ...
],
所以你需要在两个地方设置全局视图变量。使用模型中的一些常见方法,配置
类来读取全局变量或任何适合您的要求。
更多关于自定义错误处理: 扩展并实现自己的异常处理程序
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?
Yes, this is normal behaviour, what is basically happening:
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).Request handling is aborted and
ErrorHandler
steps in to catch and handle that Exception.To render the Exception,
ErroHandler
usesExceptionRenderer
, which in turn creates specialErrorController
, 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 ifbeforeFilter
was called and$foo
was set, it is not longer valid.ExceptionRenderer
will use its ownrender()
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
这篇关于Cakephp 3 - 当传出异常时,var不传输到视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!