【问题标题】:Zend default route masks invalid moduleZend 默认路由屏蔽无效模块
【发布时间】:2012-07-01 21:31:38
【问题描述】:

在 application.ini 我有默认路由:

resources.router.routes.default.type = "Zend_Controller_Router_Route"
resources.router.routes.default.route = ":lang/:module/:controller/:action/*"
resources.router.routes.default.defaults.module = "default"
resources.router.routes.default.defaults.controller = "index"
resources.router.routes.default.defaults.action = "index"
resources.router.routes.default.defaults.lang = ""

问题在于,这似乎以某种方式掩盖了无效模块上的 404 错误。例如,像“/en/mmm”这样的 url 请求被路由到默认/索引/索引。然而对于 "/en/mmm/ccc" 会触发无效的控制器。

谢谢!

【问题讨论】:

    标签: php zend-framework routes


    【解决方案1】:

    据我所知,这种行为是正常的。

    我一直在查看文档和代码,似乎路由器会在/en/mmm 之类的 url 上加载默认控制器/操作。 lang:en 有效,但 mmm 与有效模块或控制器不匹配,因此使用默认路由。

    在en/mmm/ccc 的情况下,它确实会抛出 404,因为在没有有效模块的情况下,路由将与控制器/动作匹配,并且因为值无效将导致 404。我知道为什么这会导致 404,而无效的控制器只会导致调用默认路由。

    在Default Routes 的这些示例中,此活动得到了一定程度的证明:

     // Assuming the following: $ctrl->setControllerDirectory(
         array(
             'default' => '/path/to/default/controllers',
             'news'    => '/path/to/news/controllers',
             'blog'    => '/path/to/blog/controllers'
         ) );
    
     Module only: http://example/news
     //if not valid module would attempt to match controller.
     //if not valid controller would call default route
         module == news
    
     Invalid module maps to controller name: http://example/foo
         controller == foo
    
     Module + controller: http://example/blog/archive
         module     == blog
         controller == archive
    
     Module + controller + action: http://example/blog/archive/list
     //all three must be valid or 404
         module     == blog
         controller == archive
         action     == list
    
     Module + controller + action + params:
     http://example/blog/archive/list/sort/alpha/date/desc
         module     == blog
         controller == archive
         action     == list
         sort       == alpha
         date       == desc
    

    下面的代码摘录似乎是我找到的最好的例子来证明这种行为。

    //excerpt from Zend_Controller_Router_Route_Module
    
    if ($this->_moduleValid || array_key_exists($this->_moduleKey, $data)) {
                if ($params[$this->_moduleKey] != $this->_defaults[$this->_moduleKey]) {
                    $module = $params[$this->_moduleKey];
                }
            }
            unset($params[$this->_moduleKey]);
    
            $controller = $params[$this->_controllerKey];
            unset($params[$this->_controllerKey]);
    
            $action = $params[$this->_actionKey];
            unset($params[$this->_actionKey]);
    
            foreach ($params as $key => $value) {
                $key = ($encode) ? urlencode($key) : $key;
                if (is_array($value)) {
                    foreach ($value as $arrayValue) {
                        $arrayValue = ($encode) ? urlencode($arrayValue) : $arrayValue;
                        $url .= self::URI_DELIMITER . $key;
                        $url .= self::URI_DELIMITER . $arrayValue;
                    }
                } else {
                    if ($encode) $value = urlencode($value);
                    $url .= self::URI_DELIMITER . $key;
                    $url .= self::URI_DELIMITER . $value;
                }
            }
    
            if (!empty($url) || $action !== $this->_defaults[$this->_actionKey]) {
                if ($encode) $action = urlencode($action);
                $url = self::URI_DELIMITER . $action . $url;
            }
    
            if (!empty($url) || $controller !== $this->_defaults[$this->_controllerKey]) {
                if ($encode) $controller = urlencode($controller);
                $url = self::URI_DELIMITER . $controller . $url;
            }
    
            if (isset($module)) {
                if ($encode) $module = urlencode($module);
                $url = self::URI_DELIMITER . $module . $url;
            }
    
            return ltrim($url, self::URI_DELIMITER);
        }
    

    希望这会有所帮助。

    【讨论】:

    • 嗯,因为我想在这种情况下使用 404,所以我在默认模块索引控制器中应用了“脏”解决方案:public function indexAction() { if($this->getRequest()->getParam('module') != 'default'){ throw new Zend_Controller_Action_Exception($this->translate("Page not found"),404); } }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多