使用Silex自定义路由配置

时间:2013-02-03 19:19:01

标签: symfony routing yaml silex

我知道Silex方法的基础,其中所有应用程序逻辑都在一个文件中。但我的应用程序可能有20多个控制器。所以我想有一个方便的地图来管理路由器。

我的问题是搜索我能​​够将路由器转换为单独文件的解决方案。在最好的情况下,文件必须是YAML类型:

# config/routing.yml

_home:
    pattern: /
    defaults: { _controller: MyProject\Controller\MyController::index }

但本机也是一个很好的案例(对我来说):

$routes = new RouteCollection();

$routes->add(
    'home',
    new Route('/', array('controller' => 'MyProject\Controller\MyController::index')
));

return $routes;

第二种情况的问题是我必须为每个路由规则使用 match()函数。一点也不清楚。

解决此问题的方法有哪些?条件是我想使用现有的API Silex或Symfony2的组件。

小记

我的Controller类没有使用 ControllerProviderInterface 。这是一个独立的课程。

4 个答案:

答案 0 :(得分:10)

首先,Silex的基础并不是你把所有东西放在一个文件中。 Silex的基础是您创建自己的“框架”,这是您自己组织应用程序的方式。

  

“如果您对制定所有自己的架构决策感到满意,请使用silex,如果没有,则使用完整的堆栈Symfony2。”    - Dustin Whittle

在Silex的创建者创建的this blogpost中了解更多相关信息。


如何解决您的问题

您基本上想要的是解析Yaml文件并从每个解析的路由中获取patterndefaults._controller设置。

要解析Yaml文件,您可以使用Symfony2的the Yaml Component。你得到一个数组,你可以使用它来添加到Silex的路由:

// parse the yaml file
$routes = ...;
$app = new Silex\Application();

foreach ($routes as $route) {
    $app->match($route['pattern'], $route['defaults']['_controller']);
}

// ...
$app->run();

答案 1 :(得分:5)

我以为我会在这里添加我的方法,虽然其他人可能会工作,但实际上并没有一个简单的解决方案。添加FileLocator / YamlFileLoader会增加我在应用程序中不想要读取/解析yaml文件的批量加载。

<强>作曲

首先,您需要包含相关文件。 symfony YAML组件,config service provider之前的someone who actively works on Silex非常简单实用。

"require": {
    "symfony/yaml": "~2.3",
    "igorw/config-service-provider": "1.2.*"
}

文件

假设您的路线文件如下所示(routes.yml):

config.routes:
  dashboard:
    pattern:  /
    defaults: { _controller: 'IndexController::indexAction' }
    method:   GET

<强>注册

单独注册每个yaml文件。文件中的第一个键是它在$app变量下可用的名称(由疙瘩服务定位器处理)。

$this->register(new ConfigServiceProvider(__DIR__."/../config/services.yml"));
$this->register(new ConfigServiceProvider(__DIR__."/../config/routes.yml"));
// any more yaml files you like

<强>路线

您可以使用以下方法获取这些路线:

$routes = $app['config.routes']; // See the first key in the yaml file for this name
foreach ($routes as $name => $route)
{
    $app->match($route['pattern'], $route['defaults']['_controller'])->bind($name)->method(isset($route['method'])?$route['method']:'GET');    
}
例如,

->bind()允许您“命名”您的网址,以便在树枝内使用 ->method()允许您指定POST |得到。你会注意到,如果路线没有指定方法,我会在那里使用三元组来“GET”。

答案 2 :(得分:0)

好的,我就是这样解决的。

此方法是我的应用程序的一部分,在 run()

之前调用
# /src/Application.php

...

protected function _initRoutes()
{
    $locator = new FileLocator(__DIR__.'/config');
    $loader = new YamlFileLoader($locator);

    $this['routes'] = $loader->load('routes.yml');
}

应用程序类是我自己的,它扩展了Silex \ Application。

配置文件:

# /src/config/routes.yml
home:
    pattern: /
    defaults: { _controller: '\MyDemoSite\Controllers\DefaultController::indexAction' }

它适用于我!

<强> UPD

我认为这是添加集合的正确选择:

$this['routes']->addCollection($loader->load('routes.yml'));

更灵活。

答案 3 :(得分:0)

您可以扩展routes服务(RouteCollection),并加载包含FileLocatorYamlFileLoader的YAML文件:

use Symfony\Component\Config\FileLocator;
use Symfony\Component\Routing\Loader\YamlFileLoader;

$app->extend('routes', function($routeCollection) {

    $locator    = new FileLocator([__DIR__ . '/../config']);
    $loader     = new YamlFileLoader($locator);
    $collection = $loader->load('routes.yml');

    $routeCollection->addCollection($collection);

    return $routeCollection;

});

但您需要symfony/configsymfony/yaml依赖项。