我正在使用Zend framework 1.12,尝试提出自定义路由。
我正在尝试制作看似facebook的个人资料网址(http://facebook.com/username)的内容。所以,起初我尝试过类似的东西:
$router->addRoute(
'eventName',
new Zend_Controller_Router_Route(
'/:eventName',
array(
'module' => 'default',
'controller' => 'event',
'action' => 'detail'
)
)
);
在我尝试运行mydomain.com/something时,我一直收到以下错误:
致命错误:未捕获的异常'Zend_Controller_Router_Exception' 消息中未指定“eventName” /var/desenvolvimento/padroes/zf/ZendFramework-1.12.0/library/Zend/Controller/Plugin/Broker.php 在336行
不仅我无法使这段代码工作,我的所有默认路由(显然)都被覆盖了。所以我有,例如,“mydomain.com/admin”之类的东西应该把我发送到索引控制器上的“admin”模块,但现在返回相同的错误(因为它与/的模式相同) eventName的)。
我需要做的是创建这个自定义路线,而不覆盖默认路线并实际工作(dûh)。
我已经在谷歌检查了在线文档和很多(很多)的东西,但我没有发现任何与我得到的错误有关的内容或如何不覆盖默认路由。我很感激任何能指出正确方向的事情。
感谢。
EDIT¹: 我设法让它工作,但我根本没有使用任何路由。我刚刚制作了一个插件:
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 ......
答案 0 :(得分:3)
以LIFO为基础应用/匹配路由。正如routing docs注意:
注意:反向匹配 路由按相反顺序匹配,因此请确保首先定义最通用的路由。
所以,为了让你的“静态”路由(静态,从他们不从数据库中提取的意义,/admin
等)应用于你的动态路由(/:eventName
) ,确保在执行流程中定义静态的以后。
实际上,这意味着您无法在引导期间定义静态路由,因此您必须在具有routeStartup
挂钩的插件中执行此操作。也许,两个插件:一个用于动态路由,另一个用于静态路由,只需确保设置插件的优先级,以便稍后添加静态路由。
答案 1 :(得分:2)
您获得的错误可能来自您在模板中的URL帮助程序调用。你需要为此指定eventName参数,例如:
<a href="<?=$this->url(array('eventName' => 'foo'), 'eventName')?>">Something</a>
您的其他问题的答案取决于您是否拥有静态,不变的事件列表或非事件URL。您需要为路由器提供一种方法来确定/foo
是事件还是控制器。您可以通过将可能的事件硬编码到事件路径,为其他非事件URL硬编码路由,或者(如果您的事件是动态的并且基于某些数据库内容)为您的事件路由编写自定义路由类来执行此操作执行查找以查看给定字符串是否为事件。
答案 2 :(得分: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...
一旦你在调用你的eventName的action
上,你可以检查是否== admin,稍后你可以通过指定需要加载哪个动作来定义一个重新路由,在那个条件下
简单? :)
答案 3 :(得分:0)
定义eventName,即使它不是必需的,也可以将其留空。