在ZF2路由未找到异常时调度Controller的操作

时间:2013-12-02 06:43:01

标签: php zend-framework2

我希望在Zf2引发路由未找到异常时调度另一个控制器动作以显示我的自定义页面(我不想显示自定义错误页面)。我正在从Zf2中的数据库处理动态URL,只有在找不到路由时才会发生。 我在bootstrap函数中添加了一个事件

$event->attach('route', array($this, 'loadConfiguration'), 2);
在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';
 }
}
获取控制器和操作后

我只希望调度员转发此控制器。

2 个答案:

答案 0 :(得分:1)

我的项目需要类似的东西。我最后在module.config.php中添加了一个'catchall'规则

'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 ...
)

将其作为routes数组中的第一项,以使其具有最低优先级。然后你可以让你的customePageAction做任何你想做的事情!

答案 1 :(得分:0)

只是没有真正回答你问题的事情:

  

我正在使用Zf2中来自数据库的动态URL,只有在找不到路径时才会发生。

有两种方法可以更有效地实现这一目标。如果路线不多,您可以在route事件之前加载它们。例如,您在bootstrap查询所有数据库路由并将它们注入路由堆栈。

另一种方法是创建一个“全部捕获”路径,该路线在所有路线都失败后始终匹配。然后,您没有“找不到路线”,但您的默认路线是匹配的。然后,这将查找匹配的数据库记录。如果没有找到,您只需返回404响应。

在#1的情况下,直接调度由数据库路由映射的控制器。在第二种情况下,您在“数据库控制器”中并希望调度由数据库路由映射的控制器,您使用转发插件:

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

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

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