2016-01-20 57 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() 
)); 

上面的代码,如果检测到重复的路由,则删除以前的路由并存储新的路由。

我希望我没有错过任何实现这个结果的简单方法。