Обработка ошибок в CakePHP 2.0. Сбежавший видВарс

Я столкнулся со странной проблемой с ошибками в Cake 2, которой у меня никогда не было в 1.3.

Когда возникает какое-либо исключение (например, NotFoundException), Cake начинает обрабатывать ошибки. По умолчанию он создает экземпляр CakeErrorController и выполняет все эти действия (см. source) и.. экранирует viewVars. Но у меня есть некоторые переменные представления, установленные в beforeRender моего AppController, и я не хочу, чтобы они экранировались, потому что они содержат html и должны отображаться в расположение. В чем причина такого поведения? Как я могу сказать Торту не делать этого?

Спасибо.

Обновление:

Что ж. Я разработал некоторое решение:

Я создал Controller/AppErrorController.php:

App::uses('CakeErrorController', 'Controller');

class AppErrorController extends CakeErrorController {
    public function beforeRender() {
        AppController::beforeRender();
    }
}

и Lib/Error/AppExceptionRenderer.php:

App::uses('ExceptionRenderer', 'Error');

class AppExceptionRenderer extends ExceptionRenderer {
    protected function _getController($exception) {
        App::uses('AppErrorController', 'Controller');
        if (!$request = Router::getRequest(false)) {
            $request = new CakeRequest();
        }
        $response = new CakeResponse(array('charset' => Configure::read('App.encoding')));
        try {
            $controller = new AppErrorController($request, $response);
        } catch (Exception $e) {
            $controller = new Controller($request, $response);
            $controller->viewPath = 'Errors';
        }
        return $controller;
    }
}

И в Config/core.php я установил:

Configure::write('Exception', array(
    ...,
    'renderer' => 'AppExceptionRenderer',
    ...
));

Похоже, это работает так, как ожидалось, но есть ли более элегантное решение?

Благодарю вас.


person ok32    schedule 20.12.2011    source источник
comment
Мне тоже кажется странным, что они написали метод beforeRender только для того, чтобы избежать viewVars, я надеюсь, что кто-то прояснит это. Но в любом случае, ваш подход выглядит чистым.   -  person luchomolina    schedule 22.12.2011


Ответы (1)


Вероятно, это также связано с тем, что CakeErrorController используется для всех исключений, поэтому платформа может передать любое сообщение для любой ошибки, не беспокоясь о внедрении HTML или искаженном выводе. Я предполагаю, что речь идет о надежном выводе, поскольку документы Cake описывают контроллер как "[опущено] несколько обычных обратных вызовов, чтобы ошибки всегда отображались". Это простой, урезанный контроллер для определенной цели.

К сожалению, это означает, что они жестко запрограммировали метод beforeRender CakeErrorController, поэтому отключить его невозможно. Единственные простые варианты, о которых я могу думать, - это хаки...

  1. Создайте собственное представление ошибок, которое использует функцию PHP htmlspecialchars_decod() для преобразования экранированного текста обратно в неэкранированный текст. (Если вы хотите быть тщательным, вы также можете проверить кодировку и т. д. По сути, обратите внимание на то, что h() сделал с вашим нить)
  2. Преобразуйте свое сообщение в объект (поскольку beforeRender не избегает объектов).

К счастью, в документации есть правильный обходной путь, и вы уже разобрались с ним.

Кажется, что нужно проделать большую работу только для того, чтобы вывести HTML-код в ваше представление, потому что для этого требуется много работы. Предполагается, что MVC поможет разделить ваши проблемы, но вы искажаете это разделение, создавая HTML в своем контроллере, а не в своем представлении.

person Farray    schedule 04.02.2012