2010-10-22 139 views
0

我使用的是自定義的路由器,使像網頁:如何在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頁面不存在消息。

我該如何做到這一點?

回答

1

我認爲你的意思是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函數應該有一個緩存機制來阻止每個請求上的數據庫查詢。

+0

謝謝,這是非常有益的! – 2010-10-24 14:53:44

+0

前端控制器插件只有一個問題。現在每個$ category->名稱在控制器中都有自己的操作。如果您希望所有類別名稱使用相同的categorynameAction,只需更改'action'=>'categoryname'即可。 – 2010-10-24 18:01:58

+0

這是正確的。如果你想將網址路由到所有相同的動作,它就更簡單了(參見我的回答頂部的假設)。 路由很簡單:「category /:category」,併爲該路由添加一個動作(「categoryName」)。然後在categorynameAction中,參數「category」可以通過$ this - > _ getParam(「category」)獲得。 – 2010-10-24 18:09:00