2

我正在使用 Zend 框架 1.12,试图提出自定义路由。

我正在尝试创建看起来像 facebook 的个人资料 URL ( http://facebook.com/username ) 的东西。所以,起初我尝试了这样的事情:

$router->addRoute(
            'eventName',
            new Zend_Controller_Router_Route(
                '/:eventName', 
                array(
                    'module' => 'default', 
                    'controller' => 'event', 
                    'action' => 'detail'
                )
            )
        );

每当我尝试运行 mydomain.com/something 时,我都会收到以下错误:

致命错误:在第 336 行的 /var/desenvolvimento/padroes/zf/ZendFramework-1.12.0/library/Zend/Controller/Plugin/Broker.php 中未捕获异常 'Zend_Controller_Router_Exception' 并带有消息 'eventName is not specified'

不仅我无法使那段代码工作,我所有的默认路由(显然)都被覆盖了。因此,例如,我有诸如“mydomain.com/admin”之类的东西应该将我发送到 Index 控制器上的“admin”模块,但现在返回相同的错误(因为它与 / 的模式相同:事件名称)。

我需要做的是创建这个自定义路由,而不覆盖默认路由并实际工作(dûh)。

我已经检查了在线文档和谷歌上的很多(很多)东西,但我没有找到与我遇到的错误或如何不覆盖默认路由相关的任何内容。我会很感激任何可以为我指明正确方向的东西。

谢谢。


编辑¹:我设法让它工作,但我根本没有使用任何路由。我刚刚用以下内容制作了一个插件:

public function preDispatch(\Zend_Controller_Request_Abstract $request) {

    if (!\Zend_Controller_Front::getInstance()->getDispatcher()->isDispatchable($request)) {

        $request->setModuleName($this->_eventRouter["module"]);
        $request->setControllerName($this->_eventRouter["controller"]);
        $request->setActionName($this->_eventRouter["action"]);

    }

}

不过,这感觉像是一个丑陋的解决方法……正如Tim Fountain指出的那样,我的事件是动态的(我从数据库中加载它们),所以我无法对其进行硬编码。此外,我当前的实现使我不必对每个模块/控制器/动作组合进行硬编码。

我只想知道是否有办法避免使用插件。


EDIT²:我不再做那个糟糕的插件了。我弄清楚是什么导致了路由器错误。我的路由定义没有变量“eventName”的有效默认值。我的解决方法是:

$router->addRoute(
        'eventName',
        new Zend_Controller_Router_Route(
            '/:eventName', 
            array(
                'module' => 'default', 
                'controller' => 'event', 
                'action' => 'detail',
                'eventName' => ''
            )
        )
    );

我仍然无法创建具有“冲突”模式的路由,例如/admin/:eventName。如果有办法让/admin覆盖/:eventName ...

4

4 回答 4

3

路线以 LIFO 为基础应用/匹配。正如路由文档所指出的:

注意:反向匹配路由以相反的顺序匹配,因此请确保首先定义最通用的路由。

因此,为了让您的“静态”路由(静态,在某种意义上它们不从数据库中提取/admin等)应用于您的动态路由( /:eventName),请确保稍后在执行流程中定义静态路由.

实际上,这意味着您无法在引导期间定义静态路由,因此您必须在带有routeStartup钩子的插件中进行。也许,两个插件:一个用于您的动态路由,另一个用于静态路由,只需确保设置了插件的优先级,以便稍后添加静态路由。

于 2012-11-26T06:50:06.630 回答
2

您收到的错误可能来自模板中的 URL 帮助程序调用。您需要为此指定 eventName 参数,因为您已将其设为必需,例如:

<a href="<?=$this->url(array('eventName' => 'foo'), 'eventName')?>">Something</a>

您的其他问题的答案在一定程度上取决于您是否拥有静态、不变的事件列表或非事件 URL。您需要为路由器提供一种方法来确定/foo是事件还是控制器。为此,您可以将可能的事件硬编码到您的事件路由中,为您的其他非事件 URL 硬编码路由,或者(如果您的事件是动态的并且基于某些数据库内容)为您的事件路由编写一个自定义路由类,它可以进行查找以查看给定的字符串是否是事件。

于 2012-10-30T12:33:31.053 回答
0

由于您使用的是 Zend Framework 1.x

这是我在这里添加的解决方案:How to redirect Error Page and perform Routes in Zend Framework 1.x

此外,为了让生活更轻松......这里是:

I am still unable to create routes with "conflicting" patterns, such as /admin and /:eventName. If only there was a way to make /admin override /:eventName...

一旦你在action调用你的eventName,你可以检查那个== admin,稍后你可以通过指定需要加载哪个动作来定义重新路由,在那个条件下。

简单的?:)

于 2012-11-23T08:24:19.040 回答
0

定义 eventName,即使它不是必需的,也可以将其留空。

于 2012-11-26T05:05:05.997 回答