如何在Zend-Framework中创建自定义路由器?
我使用的是自定义的路由器,使像网页:如何在Zend-Framework中创建自定义路由器?
mytutorialsite.com/category/:categoryname
# added to application.ini
resources.router.routes.categorynameOnCategory.route = /category/:categoryname
resources.router.routes.categorynameOnCategory.defaults.module = default
resources.router.routes.categorynameOnCategory.defaults.controller = category
resources.router.routes.categorynameOnCategory.defaults.action = categoryname
我也有数据库表“类别”中,所有类别的存储。例如,假设有以下几类当前存储在我的数据库:
- html
- css
- js
- php
这意味着,以下页面存在:
- mytutorialsite.com/category/html
- mytutorialsite .com/category/css
- mytutorialsite.com/category/js
- mytutorialsite.com/category/php
但是,当你访问一个页面,未在数据库中列出,像一个类别名称:
- mytutorialsite.com/category/foo
你应该得到404页面不存在消息。
我该如何做到这一点?
我认为你的意思是categoryname作为你的路由中的动作:categoryname应该用作一个动作?有两种方法可以使用。首先,您只添加路由到存在类别的路由器。当请求category/foo时,路由器将无法识别路由并抛出404错误。
第二个选项是你捕获所有类别/ *路线,并在你的行动中检查是否存在类别。
对于第一个选项,添加一个带有routeStartup函数的frontController插件。在这个钩子你可以这样做:
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
// Get the router
$router = Zend_Controller_Front::getInstance()->getRouter();
// Fetch all your categories
$category = new Application_Model_Category;
$categories = $category->fetchAll();
// Loop and add all individual categories as routes
foreach ($categories as $category) {
$route = 'category/:' . $category->name;
$params = array(
'module' => 'default',
'controller' => 'category',
'action' => $category->name
);
$route = new Zend_Controller_Router_Route($route, $params);
$router->addRoute($category->name, $route);
}
}
另一种方法是更简单的路线。在你的application.ini:
resources.router.routes.category.route = "category/:action"
resources.router.routes.category.module = "default"
resources.router.routes.category.controller = "category"
现在从类别中的所有请求/ SOMETHING必去的默认模块,类别控制器。调度员检查动作SOMETHING是否存在。当它发生时,它执行该动作。如果没有,Zend_Controller_Action_Exception(“action does not exist”)就是抛出。
所以简而言之,这两种方法都有效。随着第一个你得到更多的控制。第二种更简单,但当例如categoryController中的editAction,addAction或removeAction存在,它们也可以被触发(所以要小心该方法)。
PS。当然,routeStartup函数应该有一个缓存机制来阻止每个请求上的数据库查询。
谢谢,这是非常有益的! – 2010-10-24 14:53:44
前端控制器插件只有一个问题。现在每个$ category->名称在控制器中都有自己的操作。如果您希望所有类别名称使用相同的categorynameAction,只需更改'action'=>'categoryname'即可。 – 2010-10-24 18:01:58
这是正确的。如果你想将网址路由到所有相同的动作,它就更简单了(参见我的回答顶部的假设)。 路由很简单:“category /:category”,并为该路由添加一个动作(“categoryName”)。然后在categorynameAction中,参数“category”可以通过$ this - > _ getParam(“category”)获得。 – 2010-10-24 18:09:00