Symfony2 - 2路由到同一个bundle(可选参数)

时间:2015-06-24 15:15:18

标签: php symfony

我需要使用2个不同的网址访问我的网站,例如:

  

/ blog =>首页
  / blog / article / 1 =>文章页面(等)
  / abcde / blog =>首页
  / abcde / blog / article / 1 =>文章页面(等)

当我的URL中有“abcde”时,我需要运行相同的控制器/操作,但能够获得此“abcde”值(此参数会产生一些更改)。

我发现了许多类似的问题,但从来没有找到我想要的问题:

  • 我不是在寻找语言/翻译路由包
  • “abcde”参数必须为可选
  • 我的捆绑包有几个控制器和操作,我不想为每个编写2个路由。 (每次添加新控制器/操作时,我都不想更新任何内容。)
  • 初始 app / config / routing.yml

    mywebsite_blog:
        resource: "@MywebsiteBlogBundle/Resources/config/routing.yml"
        prefix:   /blog/
    
  • 如果我只是添加第二条路线,因为resource是相同的,它会覆盖第一条路线。

  • 我尝试在初始路线上添加可选参数:

    mywebsite_blog:
        resource: "@MywebsiteBlogBundle/Resources/config/routing.yml"
        prefix:   /{_label}/blog/
        defaults: {_label: mylabel}
        requirements:
            _label: .*
    

这样我可以访问/abcde/blog//blog,但不能访问/blog(404)。

仅使用 routing.yml 找不到如何解决我的问题(如果有可能我会很乐意了解如何并停在那里),我读到{ {3}}关于Symfony doc。我不确定我是否会朝着正确的方向前进,但我尝试了它并设法做了一些事情,但仍然不是我想要的。

LabelLoader.php

class LabelLoader extends Loader {
    private $loaded = false;

    public function load($resource, $type = null) {
        if (true === $this->loaded) {
            throw new \RuntimeException('Do not add the "label" loader twice');
        }

        $routes = new RouteCollection();

        // Prepare a new route (this is were I tried to play with it)
        $path = '/{_label}/blog/';
        $defaults = array(
            '_controller' => 'MywebsiteBlogBundle:Index:home',
        );
        $route = new Route($path, $defaults);

        // Add the new route to the route collection
        $routeName = 'labelRoute';
        $routes->add($routeName, $route);

        $this->loaded = true;

        return $routes;
    }

    public function supports($resource, $type = null) {
        return 'label' === $type;
    }
}

这样,/blog/abcde/blog按照我想要的方式运作。我可以访问我的 _init()函数中的_label变量(我正在使用监听器和InitializableControllerInterface,以防这里知道很重要),检查如果是空的,等等 但显然它只适用于一个控制器/动作(Index:home)。我想改变它,以便它可以用于我的整个MywebsiteBlogBu​​ndle。

在我的自定义Loader中,我想测试类似的东西:

$routes = new RouteCollection();

// Hypotetical function returning all the routes I want to have twice.
// Methods getPath() and getController() called below are hypotetical too.
$mywebsiteBlogRoutes = getExisitingMywebsiteBlogBundleRoutes(); 

foreach($mywebsiteBlogRoutes as $blogRoute) {

    // Prepare a new route
    $path = '/{_label}/blog/'.$blogRoute->getPath();
    $defaults = array(
        '_controller' => $blogRoute->getController(),
    );
    $route = new Route($path, $defaults);

    // Add the new route to the route collection
    $routeName = 'labelRoute';
    $routes->add($routeName, $route);
}

可是:

  • 看起来不是很干净(但如果这是我现在唯一能找到它的方法,我会尝试一下)

  • 我试图让所有路线都显示为How to Create a custom Route Loader ,并且在我尝试$collection = $router->getRouteCollection();时,我发现了“无法检测到通知参考”错误,我无法修复此问题。我想知道这里发生了什么。 编辑: 我修复了它。不过,我认为这不是一个非常干净的解决方案。

我应该回到routing.yml还是可以使用自定义路由加载器做一些事情?

1 个答案:

答案 0 :(得分:3)

您应该在routing.yml

中尝试此操作
mywebsite_blog:
    resource: "@MywebsiteBlogBundle/Resources/config/routing.yml"
    prefix:   /{_label}blog/
    defaults: {_label: mylabel/}
    requirements:
        _label: ([\w\d]+/)?

结果:

app/console router:match /mylabel/blog/  # OK
app/console router:match /blog/          # OK