Php Zend 2:如何使用自定义控制器配置错误?

Php Zend 2:如何使用自定义控制器配置错误?,php,model-view-controller,zend-framework2,Php,Model View Controller,Zend Framework2,我的问题是关于定制Zend 2中如何处理错误 假设我想自定义布局,以便在控制器中的操作中执行此操作: $layout=$this->layout(); $myNav=newviewmodel(数组('nav'=>$this->getNav()); $myNav->setTemplate('layout/nav'); $layout->addChild($myNav,'navigation'); 当我将其放入控制器进行常规(即非404)查看时,效果非常好。现在我自定义了布局,以便我可以执行,并且

我的问题是关于定制Zend 2中如何处理错误

假设我想自定义布局,以便在控制器中的操作中执行此操作:

$layout=$this->layout();
$myNav=newviewmodel(数组('nav'=>$this->getNav());
$myNav->setTemplate('layout/nav');
$layout->addChild($myNav,'navigation');
当我将其放入控制器进行常规(即非404)查看时,效果非常好。现在我自定义了布局,以便我可以执行
,并且
布局/nav.phtml
启动,一切正常

现在,假设我想在呈现错误时执行完全相同的操作。我需要能够在错误处理程序将自己的
ViewModel(…)
返回到
error/404.phtml
模板之前以某种方式注入上述代码

你是怎么做到的

我怀疑这类似于在
module.config.php
中为服务管理器设置正确的类:

“服务管理器”=>阵列(
“服务”=>数组(
“错误\u处理程序”=>“MyModule\Controller\MyCustomErrorController”
//等等。。。
我该怎么做

更新:

在我的
Module.php
中,我附加了一个用于
MvcEvent::EVENT\u DISPATCH\u ERROR
的方法。变量a有效,变量B无效。所以你不能在这里使用partials??我缺少一些真正基本的东西吗

变体A

公共函数onDispatchError(MvcEvent$事件)
{
$sm=$event->getApplication()->getServiceManager();
$vm=$event->getViewModel();
$vm->setVariable('nav','test do i work?');
//工作
}
变体B

公共函数onDispatchError(MvcEvent$事件)
{
$sm=$event->getApplication()->getServiceManager();
$vm=$event->getViewModel();
$nav=新视图模型(数组('test'=>'hello here');
$nav->setTemplate('layout/simpletest');//内容:
$vm->addChild($nav,'nav');
//在模板中,没有任何。。。
}

您可以连接到偶数以处理404触发时发生的情况:

Module.php

public function onBootstrap(MvcEvent $e)
{
    $eventManager = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
    /**
     * Log any Uncaught Errors
     */
    $sharedManager = $e->getApplication()->getEventManager()->getSharedManager();
    $sm = $e->getApplication()->getServiceManager();
    $sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
         function($e) use ($sm) {
            /**
             * Decide what to do now we've got a problem...
             * Log the issue etc..
             * You could forward to some custom controller if you wanted..
             */
            //$sm->get('Zend\Log\Logger')->crit('an error occurred... bla');
            $controller = $e->getTarget();
            //$routeMatch = $e->getRouteMatch();
            $controller->layout('somelayout'); // possibly change the layout..
         }
    );
}

您可以连接到偶数以处理404触发时发生的情况:

Module.php

public function onBootstrap(MvcEvent $e)
{
    $eventManager = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $moduleRouteListener->attach($eventManager);
    /**
     * Log any Uncaught Errors
     */
    $sharedManager = $e->getApplication()->getEventManager()->getSharedManager();
    $sm = $e->getApplication()->getServiceManager();
    $sharedManager->attach('Zend\Mvc\Application', 'dispatch.error',
         function($e) use ($sm) {
            /**
             * Decide what to do now we've got a problem...
             * Log the issue etc..
             * You could forward to some custom controller if you wanted..
             */
            //$sm->get('Zend\Log\Logger')->crit('an error occurred... bla');
            $controller = $e->getTarget();
            //$routeMatch = $e->getRouteMatch();
            $controller->layout('somelayout'); // possibly change the layout..
         }
    );
}

Zf2使用module.config.php文件设置错误处理:

'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',
        ),
这将处理4xx客户端错误和5xx服务器错误

用于特定模块中的自定义错误页

namespace ModuleName;

use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\Mvc\MvcEvent;

class Module implements
    BootstrapListenerInterface,
    AutoloaderProviderInterface,
    ConfigProviderInterface
{
    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->attach('dispatch', array($this, 'loadConfiguration' ), 100);
    }

    public function loadConfiguration(MvcEvent $e)
    {
    $sm  = $e->getApplication()->getServiceManager();

        $controller = $e->getRouteMatch()->getParam('controller');
        if (0 !== strpos($controller, __NAMESPACE__, 0)) {
            //if not this module
            return;
        }

        //if this module
    $exceptionstrategy = $sm->get('ViewManager')->getExceptionStrategy();
    $exceptionstrategy->setExceptionTemplate('error/errorcustom');
    }

    public function getAutoloaderConfig(){ /* common code */ }
    public function getConfig(){ /* common code */}
}

该解决方案由来自Zf2的“samsonasik”提供,使用module.config.php文件设置错误处理:

'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',
        ),
这将处理4xx客户端错误和5xx服务器错误

用于特定模块中的自定义错误页

namespace ModuleName;

use Zend\ModuleManager\Feature\BootstrapListenerInterface;
use Zend\ModuleManager\Feature\AutoloaderProviderInterface;
use Zend\ModuleManager\Feature\ConfigProviderInterface;
use Zend\Mvc\MvcEvent;

class Module implements
    BootstrapListenerInterface,
    AutoloaderProviderInterface,
    ConfigProviderInterface
{
    public function onBootstrap(MvcEvent $e)
    {
        $eventManager        = $e->getApplication()->getEventManager();
        $eventManager->attach('dispatch', array($this, 'loadConfiguration' ), 100);
    }

    public function loadConfiguration(MvcEvent $e)
    {
    $sm  = $e->getApplication()->getServiceManager();

        $controller = $e->getRouteMatch()->getParam('controller');
        if (0 !== strpos($controller, __NAMESPACE__, 0)) {
            //if not this module
            return;
        }

        //if this module
    $exceptionstrategy = $sm->get('ViewManager')->getExceptionStrategy();
    $exceptionstrategy->setExceptionTemplate('error/errorcustom');
    }

    public function getAutoloaderConfig(){ /* common code */ }
    public function getConfig(){ /* common code */}
}

该解决方案由来自

的“samsonasik”提供,感谢您的回复。但是,这不允许我通过注入布局变量(例如
$layout->addChild(…)
)来自定义布局。感谢您的回复。但是,这不允许我通过注入布局变量(例如
$layout->addChild(…)来自定义布局
)。不幸的是,这不起作用。我猜这是一个错误,
$e->getRouteMatch()
不存在,因为没有有效的路由匹配,这导致我们首先发生了
调度。错误
事件。这只是一些未测试的示例代码,只是为了让您了解您可以访问的内容,由您决定您需要做什么:)我对示例代码很在行:)我只是想说,我不知道为什么
$e->getRouteMatch()
在没有找到路由的情况下会返回任何内容。它不会。它只是从另一个事件使用示例粘贴到那里的一些示例内容,这不是真正相关的部分,尽管关键是你可以使用事件来完成你需要的事情:)不幸的是,这不起作用。我猜,由于这是一个错误,
$e->getRouteMatch()
不存在,因为没有有效的路由匹配,这导致我们首先出现了这个
分派.error
事件。这只是一些示例代码,没有测试,只是为了让您了解可以访问的内容,这取决于你来决定你需要做什么:)我对示例代码很在行:)我的意思是我不知道为什么
$e->getRouteMatch()
在没有找到路由的情况下会返回任何东西。这不会是因为它只是从另一个事件使用示例中粘贴了一些示例内容,这并不是真正相关的部分,尽管重点是你可以使用事件来做你需要的事情:)6年后,是否仍然没有简单的解决方案?6年后,是否仍然没有简单的解决方案?