Symfony Routing:如何定义通配符的全局要求/约束​​?

时间:2015-09-06 08:16:07

标签: php symfony

Laravel具有Global Patternsdescribed here)等功能。

简而言之:您可以为通配符定义一次模式,例如Route::pattern('id', '[0-9]+'),并在路由模式中使用通配符{id},而不必重复自己。

现在,我正在尝试将symfony/routing组件集成到我自己的框架中。我看到可以使用An array of requirementsdescribed here)为每条路径定义通配符模式,我找不到全局声明它们的方法。

symfony/routing中是否有此类/类似功能?

2 个答案:

答案 0 :(得分:1)

如果您正在使用框架 - 您应该能够最终在RouteCollection(\Symfony\Component\Routing\Route()对象)中收集所有路由(\Symfony\Component\Routing\RouteCollection()对象)。这些可能是您的框架或应用程序根据您的框架定义的路由。

基本上,为了将您的URI与\Symfony\Component\Routing\Matcher\UrlMatcher()相匹配,您需要执行哪些操作。

现在,RouteCollection可以满足您的任何要求,并将它们添加到集合中的所有路由中。

所以,你需要做的就是:

无论如何在任何地方定义global requirements,但最终将它们添加到最终路线集合中,如下所示:

$globalRequirements = [
    'any' => '.*',
    'id' => '[0-9]+',
    'ident' => '[A-Za-z0-9]+',
    'date' => '[0-9]{4}-[0-9]{2}-[0-9]{2}',
    'year' => '[0-9]{4}',
];

/** @var RouteCollection $routes */
$routes->addRequirements($globalRequirements);

简单!

注意:在这种情况下,所有与requirements相同名称的现有year都将被重写。所以如果你想避免它,你必须添加一些自定义逻辑。

答案 1 :(得分:0)

您无法全局声明通配符模式。 但你可以这样做:

  1. 将您的控制器声明为服务
  2. 创建路线实例
  3. 将路径分配给池中的控制器
  4. 阅读本文应该会让你看起来更好看 http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html http://symfony.com/doc/current/components/dependency_injection/tags.html http://symfony.com/doc/current/components/dependency_injection/compilation.html

    然后你可以创建像loader这样的东西,在加载时你可以在这个加载器中使用taged控制器服务为你的动作添加一个自定义路由定义。

    这样的事情:

    公共函数加载($ resource,$ type = null)     {         $ routes = new RouteCollection();

        foreach ($this->pool->getControllers() as $controllerKey => $controller) {
                $route = new Route($pattern, $defaults, $requirements, $options, $host, $schemes, $methods, $condition);
                $routes->add($controllerKey . '.' . $actionKey, $route);
        }
    
        return $routes;
    }
    

    它只是一个例子,所以你可以弄清楚如何创建路由实例。