简体   繁体   English

找不到ZF2路由上的控制器操作异常

[英]Dispatch a Controller's Action on ZF2 route not found exception

I want want dispatch another controller action when Zf2 raise route not found exception to display my custom page ( i dont want to display a custom error page). 我想在Zf2引发路由未找到异常时调度另一个控制器动作来显示我的自定义页面(我不想显示自定义错误页面)。 I am working on dynamic url from database in Zf2 which will occur only when route not found. 我正在Zf2中的数据库中处理动态url,仅在未找到路由时才会发生。 i added a event in bootstrap function 我在引导函数中添加了一个事件

$event->attach('route', array($this, 'loadConfiguration'), 2);

in loadConfiguration function i added to load 在loadConfiguration函数中我添加到加载

public function loadConfiguration(MvcEvent $e){
    $application   = $e->getApplication();
    $sm = $application->getServiceManager();
    $router = $sm->get('router');
    $request = $sm->get('request');
    $matchedRoute = $router->match($request);
if (null == $matchedRoute) { 
        $request_uri = $e->getRequest()->getrequestUri();
        $dbAdaptor = $e->getApplication()->getServiceManager()->get('Zend\Db\Adapter\Adapter');
        $url_table = new UrlMappingTable($dbAdaptor);
        $url_data = $url_table->find($request_uri);
        $controller = $url_data['controller'];
        $action = $url_data['action'];
        $id = $url_data['post_id'];
        $original_url = $url_data['original_url'];
        $alias = $sm->get('Application\Router\Alias');

            $alias->setNavigation($original_url);

        if(isset($url_data)){
        $url = $e->getRouter ()->assemble (array('controller' => $controller,
                                                     'action' => $action ,
                                                      'id' => $id,
                                              ), array (
                                            'name' => 'myurl'
                                            ) );
       }

 print 'no route match';
 }
}

after getting the controller and action i just want the dispatcher to forward this controller. 得到控制器和动作后,我只希望调度程序转发此控制器。

I needed something similar for my project. 我的项目需要类似的东西。 I ended up just adding a 'catchall' rule in module.config.php 我最终只是在module.config.php中添加了一个'catchall'规则

ie

'router' => array(
    'routes' => array(
         'catchAll' => array(
            'type' => 'regex',
            'options' => array(
                'regex' => '/(?<page>.+)',
                'defaults' => array(
                    'controller' => 'Project\Controller\MyController',
                    'action' => 'customPage',
                ),
                'spec' => '/%page%',
            ), 
        ),
        //Other route items ...
    ),
    //Other stuff ...
)

Place this as the first item in the routes array so it has the lowest precedence. 将其作为路由数组中的第一项,使其优先级最低。 Then you can have your customePageAction to do whatever you want! 然后,您可以让customePageAction做任何您想做的事!

Just something not really answering your question: 只是有些东西无法真正回答您的问题:

I am working on dynamic url from database in Zf2 which will occur only when route not found. 我正在Zf2中的数据库中处理动态url,仅在未找到路由时才会发生。

There are two ways you can achieve this much more efficiently. 有两种方法可以更有效地实现这一目标。 If there aren't much routes, you can load them before the route event. 如果没有太多路由,则可以在route事件之前加载它们。 For example, you query on bootstrap all your database routes and inject them into the route stack. 例如,您在bootstrap查询所有数据库路由,并将它们注入到路由堆栈中。

Another way is creating a "catch all" route which always will match after all routes failed. 另一种方法是创建“全部捕获”路由,该路由在所有路由失败后始终匹配。 Then you don't have a "route not found" but your default route is matched. 然后,您没有“找不到路由”,但是您的默认路由已匹配。 This will then look for a matching database record. 然后,它将查找匹配的数据库记录。 If none found, you just return a 404 response. 如果未找到,则只返回404响应。

In case #1, the controller mapped by your database route is directly dispatched. 在情况#1中,数据库路由所映射的控制器是直接调度的。 In the second case, you are in your "database controller" and want to dispatch your controller mapped by the database route, you use the forward plugin: 在第二种情况下,您位于“数据库控制器”中,并且想要分派由数据库路由映射的控制器,请使用forward插件:

public function matchAction()
{
    // Fetch route from db here

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

    return $this->forward($match->getController, array(
        'action' => $match->getAction()
    ));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM