2016-01-20 58 views
3

我們正在尋找使用Slim 3作爲我們API的框架。我搜索了SO和Slim文檔,但無法找到問題的答案。如果我們有不同的路由文件(例如v1,v2等),並且兩個路由具有相同的簽名,則會引發錯誤。是否有任何方法級聯路由,以便使用特定簽名的最後加載路由?具有相同簽名的多條細長路線

例如,說v1.php有一個路線GET ("/test")和v2.php也包含這條路線,我們可以使用最新版本嗎?更簡單的是,如果一個路由文件包含兩個具有相同簽名的路由,是否有使用後一種方法的方法(並且沒有引發錯誤)?

類似的問題被問here但使用掛鉤(已刪除從斯利姆3%here爲)

+0

這有什麼用途,然後有重複的路線呢? – jmattheis

+0

該API可以具有不同版本的簽名。這是爲了加載它們,然後只讓最新版本「live」。基本上兩個具有相同簽名的路線會導致錯誤。 – TheAnswerIs42

+0

爲什麼不只是包含lastes版本? – jmattheis

回答

3

我看着修身代碼,我沒有找到允許重複路線的簡單方法(防止異常)。 新Slim使用FastRoute作爲依賴關係。它叫FastRoute\simpleDispatcher,並不提供任何配置可能性。即使它允許一些配置,FastRoute也沒有任何內置選項來允許重複的路由。將需要一個DataGenerator的自定義實現。

但按照上述指示,我們可以通過傳遞修身應用定製Router其中一些實例其中FastRoute::Dispatcher implementation然後使用自定義的DataGenerator得到一個定製DataGenerator

首先CustomDataGenerator(讓我們去簡單的方法,並從\FastRoute\RegexBasedAbstract\FastRoute\GroupCountBased做一些複製和粘貼)

class CustomDataGenerator implements \FastRoute\DataGenerator { 
    /* 
    * 1. Copy over everything from the RegexBasedAbstract 
    * 2. Replace abstract methods with implementations from GroupCountBased 
    * 3. change the addStaticRoute and addVariableRoute 
    * to the following implementations 
    */ 
    private function addStaticRoute($httpMethod, $routeData, $handler) { 
     $routeStr = $routeData[0]; 

     if (isset($this->methodToRegexToRoutesMap[$httpMethod])) { 
      foreach ($this->methodToRegexToRoutesMap[$httpMethod] as $route) { 
       if ($route->matches($routeStr)) { 
        throw new BadRouteException(sprintf(
         'Static route "%s" is shadowed by previously defined variable route "%s" for method "%s"', 
         $routeStr, $route->regex, $httpMethod 
        )); 
       } 
      } 
     } 
     if (isset($this->staticRoutes[$httpMethod][$routeStr])) { 
      unset($this->staticRoutes[$httpMethod][$routeStr]); 
     } 
     $this->staticRoutes[$httpMethod][$routeStr] = $handler; 
    } 
    private function addVariableRoute($httpMethod, $routeData, $handler) { 
     list($regex, $variables) = $this->buildRegexForRoute($routeData); 
     if (isset($this->methodToRegexToRoutesMap[$httpMethod][$regex])) { 
      unset($this->methodToRegexToRoutesMap[$httpMethod][$regex]); 
     } 
     $this->methodToRegexToRoutesMap[$httpMethod][$regex] = new \FastRoute\Route(
      $httpMethod, $handler, $regex, $variables 
     ); 
    } 
} 

然後自定義Router

class CustomRouter extends \Slim\Router { 
    protected function createDispatcher() { 
     return $this->dispatcher ?: \FastRoute\simpleDispatcher(function (\FastRoute\RouteCollector $r) { 
      foreach ($this->getRoutes() as $route) { 
       $r->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier()); 
      } 
     }, [ 
      'routeParser' => $this->routeParser, 
      'dataGenerator' => new CustomDataGenerator() 
     ]); 
    } 
} 

終於實例與修身的應用定製路由器

$app = new \Slim\App(array(
    'router' => new CustomRouter() 
)); 

上面的代碼,如果檢測到重複的路由,則刪除以前的路由並存儲新的路由。

我希望我沒有錯過任何實現這個結果的簡單方法。