Intereting Posts
Лучший / простой способ анализа параметров конфигурации в Sh / Bash и php Curl: несколько файлов cookie Динамически создавать массив $ filterArgs в CakePHP PHP SQL Foreach Statement Подсказка типа Php не согласуется с интерфейсами и абстрактными классами? Как объединить два массива без повторных значений? Как вы переопределите базу данных по умолчанию в вашей докторантуре по умолчанию для использования ваших локальных настроек? Zend_Paginator возвращает объекты Как сохранить номер страницы после перенаправления в CakePHP? login / logout не работает php правильно Как редактировать и водяные знаки анимированных gif, желательно через php? отправка вопроса в битбакет, используя oauth через bitbucket api Как получить доступ к удаленному каталогу и скопировать файлы в PHP Сравните два многомерных массива и несоответствующие элементы Передача данных POST из Javascript (jquery) в php-проблемы?

ZF2 – Как изменить страницу ответов на ошибку / 404? Не только шаблон, но и установка новой модели ViewModel

По умолчанию страница задана так же в массиве Application module.config:

 'template_map' => array( 'error/404' => __DIR__ . '/../view/error/404.phtml' 

Я хочу изменить страницу. Я хочу, чтобы новый ViewModel заполнен переменными. Это означает, что просто изменить шаблон недостаточно:

 'error/404' => __DIR__ . '/../view/error/my_new_404_template.phtml' 

Но я не могу понять, как это сделать. Я не вижу, как запрос приходит к 'error/404' .

  • Как создать для него новый ViewModel ?

  • Как подключить к нему переменные?

  • Как маршрут доходит до 'error/404' чтобы перехватить его?

Например, у меня есть такой метод для страницы 'error/404' :

 public function pageNotFoundAction() { $view = new ViewModel(); $view->setTemplate('error/404'); // set my template $sm = $this->getServiceLocator()->get('SessionManager'); $cont = new Container('SomeNamespace', $sm); $view->var1 = $cont->offsetGet('someValue1'); // the "error/404" template $view->var2 = $cont->offsetGet('someValue2'); // is full of variables $view->var3 = $cont->offsetGet('someValue3'); $view->var4 = "One more view variable"; // And now I return it somewhere and want it to be called // in case of "the page is not found" return $view; } 

Как сделать такое изменение? Я не могу получить систему, которую они создали, чтобы иметь дело с такими вещами, как 'error/404' . Пожалуйста помоги.

UPD 1

Еще более сложная задача. Как получить несколько страниц 'error/404' ? Хотелось бы спросить ребят, которые создали фреймворк, знают ли они, что 'not_found_template' не может иметь массив страниц 'error/404' . Как это может быть? Если я задаю этот параметр следующим образом:

 'template_map' => array( 'error/404' => __DIR__ . '/../view/error/404.phtml', 'my-page/one_more_error404' => __DIR__ . '/../view/my-page/my-page/one_more_error404.phtml', 'other_page/second_404' => __DIR__ . '/../view/other-page/one_more_error404.phtml', 'not_found_template' => array( 'error/404', 'my-page/one_more_error404', 'other-page/second_404', ); 

он выдает ошибку. 'not_found_template' заставляет вас иметь только один шаблон 'error/404' ?

Есть и другой способ. Чтобы поймать EVENT_DISPATCH_ERROR и полностью перестроить viewModel . Пещера – это макет – это root viewModel , а контент, добавленный в макет по умолчанию, – это еще один viewModel (child). Эти пункты не так четко описаны в официальных документах.

Вот как это может выглядеть в вашем Module.php :

 public function onBootstrap(MvcEvent $event) { $app = $event->getParam( 'application' ); $eventManager = $app->getEventManager(); /** attach Front layout for 404 errors */ $eventManager->attach( MvcEvent::EVENT_DISPATCH_ERROR, function( MvcEvent $event ){ /** here you can retrieve anything from your serviceManager */ $serviceManager = $event->getApplication()->getServiceManager(); $someVar = $serviceManager->get( 'Some\Factory' )->getSomeValue(); /** here you redefine layout used to publish an error */ $layout = $serviceManager->get( 'viewManager' )->getViewModel(); $layout->setTemplate( 'layout/start' ); /** here you redefine template used to the error exactly and pass custom variable into ViewModel */ $viewModel = $event->getViewModel(); $viewModel->setVariables( array( 'someVar' => $someVar ) ) ->setTemplate( 'error/404' ); }); } 

Я не уверен, что следую тому, чего вы пытаетесь достичь, можете ли вы дать ясный пример того, что вы пытаетесь сделать?

Если вы просто пытаетесь добавить переменные в переданную модель представления, вы можете даже сделать это в своем контроллере, проверьте AbstractActionController

 /** * Action called if matched action does not exist * * @return array */ public function notFoundAction() { $response = $this->response; $event = $this->getEvent(); $routeMatch = $event->getRouteMatch(); $routeMatch->setParam('action', 'not-found'); if ($response instanceof HttpResponse) { return $this->createHttpNotFoundModel($response); } return $this->createConsoleNotFoundModel($response); } /** * Create an HTTP view model representing a "not found" page * * @param HttpResponse $response * @return ViewModel */ protected function createHttpNotFoundModel(HttpResponse $response) { $response->setStatusCode(404); // Add in extra stuff from your ServiceLocator here... // $viewModel->setTemplate(..); return new ViewModel(array( 'content' => 'Page not found', )); } 

Первое состоит в создании представлений:

Модули / Yourapplication / просмотр / yourapplication / ошибка / index.phtml

Модули / Yourapplication / просмотр / yourapplication / ошибка / 404.phtml

Во-вторых, нужно зарегистрировать представления в конфигурации модуля:

В module.config.php вашего приложения

 'view_manager' => array( //[...] 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => array( //[...] 'error/404' => __DIR__ . '/../view/yourapplication/error/404.phtml', 'error/index' => __DIR__ . '/../view/yourapplication/error/index.phtml', ), // [...] ), 

Я использовал это для управления ошибкой 404 (я переместил мой сайт с spip на cms на основе ZF2):

В модуле onBootstrap:

 $eventManager->getSharedManager()->attach('*', MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onDispatchError'), -100); 

затем

 public function onDispatchError(MvcEvent $event) { $response = $event->getResponse(); if ($response->getStatusCode() == 404) { $url = $event->getRouter()->assemble(array(), array('name' => 'index')); $requestUri = $event->getRequest()->getRequestUri(); $response->getHeaders()->addHeaderLine('Location', "$url?url=$requestUri"); $response->setStatusCode(200); $response->sendHeaders(); $event->stopPropagation(true); } elseif($response->getStatusCode() == 500){ //DO SOMETHING else? return; } } 

В этом коде мы никогда не возвращаем ошибку 404, мы просто вызываем маршрут (в моем примере index) с запрошенным url как param

Надеюсь, это поможет вам.

в module.php вы также можете изменить шаблон и макет.

 function onBootstrap(EventInterface $e) { $app = $e->getApplication(); $evt = $app->getEventManager(); $evt->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this,'onDispatchError'), 100); } function onDispatchError(MvcEvent $e) { $vm = $e->getViewModel(); $vm->setTemplate('layout/blank'); } - function onBootstrap(EventInterface $e) { $app = $e->getApplication(); $evt = $app->getEventManager(); $evt->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this,'onDispatchError'), 100); } function onDispatchError(MvcEvent $e) { $vm = $e->getViewModel(); $vm->setTemplate('layout/blank'); } 

Или проще (где вы хотите):

 /* @var \Zend\Mvc\View\Http\RouteNotFoundStrategy $strategy */ $strategy = $this->getServiceLocator()->get('HttpRouteNotFoundStrategy'); $strategy->setNotFoundTemplate('application/other/404'); $view = new ViewModel(); //$view->setTemplate('application/other/404'); return $view; 

Сначала вы должны отключить стандартную notfoundstrategy и в вашем Module.php, а в случае 404 вы должны вернуть новую модель просмотра из контроллера. Пожалуйста, смотрите это сообщение: http://www.cagataygurturk.com/zf2-controller-specific-not-found-page/