Используйте один и тот же обработчик ошибок в разных модулях Zend Framework 2.

У меня много модулей в приложении Zend. В каждом модуле будут ошибки и исключения, верно? Итак, я создаю страницу ошибки в модуле приложения, и она работает.

Однако в других модулях они не могут использовать страницу ошибки. Итак, что мне делать, чтобы повторно использовать страницу с ошибкой?

Вот файл module.config.php в модуле приложения:

return array(
    ...,
    'controllers' => array(
        'invokables' => array(
            'Application\Controller\Index' => 'Application\Controller\IndexController'
        ),
    ),
    'view_manager' => array(
        'display_not_found_reason' => true,
        'display_exceptions'       => true,
        'doctype'                  => 'HTML5',
        'not_found_template'       => 'error/404',
        'exception_template'       => 'error/index',
        'template_map' => array(
            'layout/layout'           => __DIR__ . '/../view/layout/layout.phtml',
            'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
            'error/404'               => __DIR__ . '/../view/error/404.phtml',
            'error/index'             => __DIR__ . '/../view/error/index.phtml',
        ),
        'template_path_stack' => array(
            __DIR__ . '/../view',
        ),
    ),
);

Проблема возникает, когда я вручную возвращаю ответ HTTP 404 со следующим кодом:

if ( $information == null ) {
    $response = $this->getResponse();
    $response->setStatusCode(404);
    return $response;
}

Однако, когда я обращаюсь к нелегальным ресурсам, таким как http://example.com/something-do-not-exist. Я попаду на страницу ошибки 404 с исключением The requested URL could not be matched by routing.


person Haozhe Xie    schedule 07.02.2014    source источник


Ответы (3)


Перечисленная вами конфигурация определена в модуле приложения, однако она не специфична для этого модуля.

Это связано с тем, что во время начальной загрузки приложения каждый module.config.php объединяется в один массив конфигурации ( используя array_merge_recursive()). Это конфигурация, которую вы можете получить, используя $serviceManager->get('Config');

Таким образом, конфигурация является глобальной для приложения, и все ошибки (исключения) должны использовать один и тот же шаблон ошибки (application/view/error/index.phtml).

Однако имейте в виду, что порядок загрузки модулей важен; поскольку модули, загружаемые последними, всегда перезаписывают существующую конфигурацию.

person AlexP    schedule 07.02.2014
comment
Вы имеете в виду, что я должен добавить $serviceManager->get('Config'); в Module.php в других модулях? - person Haozhe Xie; 07.02.2014
comment
@HowardXie Нет, именно так вы получаете конфигурацию объединенного приложения. Если вам нужен один и тот же шаблон ошибки во всех модулях, вам больше ничего не нужно делать — опубликованный вами код должен работать для всех модулей. - person AlexP; 07.02.2014
comment
Конечно, нет. Если я использую приведенную выше конфигурацию, я должен создать страницы ошибок в каждом модуле. Потому что относительный путь /../view/error/404.phtml не существует в других модулях. - person Haozhe Xie; 07.02.2014
comment
Вам нужна только конфигурация not_found_template или exception_template в одном модуле, и она будет использоваться во всем приложении — просто пропустите эти настройки для любого другого модуля. - person AlexP; 07.02.2014
comment
Однако я дал ответ 404 в другом модуле, и страница с ошибкой не отображается. У меня на экране пустая страница. Почему? ($response = $this->getResponse(); $response->setStatusCode(404);return $response;) - person Haozhe Xie; 07.02.2014
comment
На самом деле, когда я обращаюсь к несуществующему ресурсу, я получаю страницу с ошибкой. Однако, если я верну ответ 404 вручную, я получу пустую страницу. - person Haozhe Xie; 07.02.2014

Я решаю проблему следующим кодом:

if ( $information == null ) {
    return $this->notFoundAction();
}

И это перенаправит вас на страницу глобальной ошибки.

person Haozhe Xie    schedule 07.02.2014

Почему другие модули не могут использовать страницу ошибки?

Во всяком случае, есть более чем один способ сделать это ;)

Например, вы можете определить несколько имен в вашем template_map для каждой страницы ошибок, которую вы хотите.

person jmleroux    schedule 07.02.2014