Cakephp 3 - 抛出异常时未将 var 传输到视图
Cakephp 3 - var not transmitted to view when exception thrown
在我的 AppController 中,我定义了一个必须在我的应用程序的每个视图(包括 error400.ctp、error500.ctp)中使用的变量:
// /src/Controller/AppController.php
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$foo = 'bar';
$this->set(compact('foo'));
}
它运行良好,除非抛出异常(如 NotFoundException):我收到以下错误:
Undefined variable: foo in /src/Template/Error/error400.ctp
这是 cakephp 的正常行为吗?我该如何解决这个问题?
是的,这是正常行为,基本上发生了什么:
异常被抛出(beforeFilter
被调用取决于它被抛出的位置,例如它被调用为 MissingAction 或 MissingTemplate,但不是为 MissingController)。
请求处理中止,ErrorHandler
介入以捕获并处理该异常。
为了呈现异常,ErroHandler
使用 ExceptionRenderer
,这反过来又创建了特殊的 ErrorController
,这种方式取代了原来的控制器。这也意味着,现在您有完全不同的控制器来处理请求(控制器 class 的新实例),因此即使调用了 beforeFilter
并设置了 $foo
,它也不再有效.
ExceptionRenderer
将使用自己的 render()
方法为错误页面创建输出。
要对此进行自定义,您可以扩展默认设置 ExceptionRenderer
,这样您就可以将变量设置为 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();
}
}
将此 class 设置为 app.php
中的默认 ExceptionRenderer
//...
'Error' => [
// ...
'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
// ...
],
所以你需要在两个地方设置那个全局视图变量。使用模型中的一些常用方法,Configure
class 来读取全局变量或任何适合您要求的方法。
关于自定义错误处理的更多信息:Extending and Implementing your own Exception Handlers
在我的 AppController 中,我定义了一个必须在我的应用程序的每个视图(包括 error400.ctp、error500.ctp)中使用的变量:
// /src/Controller/AppController.php
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$foo = 'bar';
$this->set(compact('foo'));
}
它运行良好,除非抛出异常(如 NotFoundException):我收到以下错误:
Undefined variable: foo in /src/Template/Error/error400.ctp
这是 cakephp 的正常行为吗?我该如何解决这个问题?
是的,这是正常行为,基本上发生了什么:
异常被抛出(
beforeFilter
被调用取决于它被抛出的位置,例如它被调用为 MissingAction 或 MissingTemplate,但不是为 MissingController)。请求处理中止,
ErrorHandler
介入以捕获并处理该异常。为了呈现异常,
ErroHandler
使用ExceptionRenderer
,这反过来又创建了特殊的ErrorController
,这种方式取代了原来的控制器。这也意味着,现在您有完全不同的控制器来处理请求(控制器 class 的新实例),因此即使调用了beforeFilter
并设置了$foo
,它也不再有效.ExceptionRenderer
将使用自己的render()
方法为错误页面创建输出。
要对此进行自定义,您可以扩展默认设置 ExceptionRenderer
,这样您就可以将变量设置为 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();
}
}
将此 class 设置为 app.php
//...
'Error' => [
// ...
'exceptionRenderer' => 'App\Error\AppExceptionRenderer',
// ...
],
所以你需要在两个地方设置那个全局视图变量。使用模型中的一些常用方法,Configure
class 来读取全局变量或任何适合您要求的方法。
关于自定义错误处理的更多信息:Extending and Implementing your own Exception Handlers