Set variables to 404 in zend framework 2

2019-06-23 22:40发布

问题:

In my controller I throw a 404 response after an If statement, something like that :

    if ($foo) {
        $this->getResponse()->setStatusCode(404);
        return; 
    }

Then, I would like to send some variables to my 404 page. In my mind, I want to do something like that :

    $this->getResponse()->setVariables(array('foo' => 'bar', 'baz' => 'bop'));
    $this->getResponse()->setStatusCode(404);
    return; 

It's not the good solution, so how I have to do that ?

And after, how to get these variables in my 404 view ?

Thank you

回答1:

Oh god..

I was so dumb

Solution :

if ($foo) {
    $this->getResponse()->setStatusCode(404);
    return array('myvar' => 'test');
}

In 404.phtml :

<?php echo $this->myvar; ?>


回答2:

I've come to this question from Google and my issue was a bit more difficult. Since 404 error could be thrown from absolutely unpredictable url, you can't be sure you catched it in some controller. Controller – is too late to catch 404 error.

The solution in my case was to catch an EVENT_DISPATCH_ERROR and totally rebuild viewModel. Cavern is that layout – is a root viewModel, and content appended into layout by default is another viewModel (child). These points are not such clear described in official docs.

Here is how it can look like in your 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->getResult();
        $viewModel->setVariables( array( 'someVar' => $someVar ) )
                  ->setTemplate( 'error/404' );
    });
}