Cakephp 3 - 当抛出异常时,var不会传输到视图

时间:2015-05-19 01:03:54

标签: error-handling cakephp-3.0

在我的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的正常行为吗?我怎么能解决这个问题?

1 个答案:

答案 0 :(得分:4)

是的,这是正常行为,基本上发生了什么:

  1. 抛出异常(根据它抛出的位置调用beforeFilter,例如调用MissingAction或MissingTemplate,但不调用MissingController)。

  2. 请求处理已中止,ErrorHandler介入以捕获并处理该异常。

  3. 要呈现异常,ErroHandler使用ExceptionRenderer,而ErrorController会创建特殊的beforeFilter,这种替换原始控制器。这也意味着,现在您有完全不同的控制器处理请求(Controller类的新实例),因此即使调用了$foo并且设置了ExceptionRenderer,它也不再有效。

  4. render()将使用自己的ExceptionRenderer方法为错误页面创建输出。

  5. 要自定义此功能,您可以扩展默认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(); } }

    app.php

    将此类设置为//... 'Error' => [ // ... 'exceptionRenderer' => 'App\Error\AppExceptionRenderer', // ... ],

    中的默认ExceptionRenderer
    Configure

    因此,您需要在两个位置设置该全局视图变量。使用模型App::uses('AppModel', 'Model'); class Feed extends AppModel {} 类中的一些常用方法来读取全局变量或适合您要求的任何变量。

    有关自定义错误处理的更多信息: Extending and Implementing your own Exception Handlers