php - Symfony2 - 2 条路由到同一个包(可选参数)

标签 php symfony

我需要我的网站可以通过 2 个不同的 URL 访问,例如:

/blog => Homepage
/blog/article/1 => Article page (etc.)
/abcde/blog => Homepage
/abcde/blog/article/1 => Article page (etc.)

当“abcde”在我的 URL 中时,我需要运行相同的 Controller /操作,但能够获得此“abcde”值(此参数会导致一些更改)。

我发现了很多类似的问题,但从来都不是我要找的:

  • 我不是在寻找语言/翻译路由包
  • “abcde”参数必须是可选
  • 我的包有多个 Controller 和操作,我不想为每个 Controller 和操作编写 2 条路由。 (我也不想每次添加新 Controller / Action 时都必须更新任何内容。)

  • 初始化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 解决我的问题(如果可能的话我会很乐意学习如何并停在那里),我读到 How to Create a custom Route Loader 在 Symfony 文档上。我不确定我会朝着正确的方向前进,但我尝试过并设法做了一些事情,但仍然不是我想要的。

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,以防在这里知道很重要),检查是否为空等。 但显然它仅适用于一个 Controller /操作 (Index:home)。我想更改此设置,以便它适用于我的整个 MywebsiteBlogBu​​ndle。


在我的自定义加载器中,我想测试如下内容:

$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);
}

但是:

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

  • 我试图让我的所有路线都读取 this answer 并且当我尝试 $collection = $router->getRouteCollection(); 时我有一个“检测到循环引用”错误无法修复。我试图了解这里发生了什么。 编辑: 我修复了它。不过,我认为这不是一个非常干净的解决方案。


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

最佳答案

你应该在你的 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

关于php - Symfony2 - 2 条路由到同一个包(可选参数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31030411/

相关文章:

php - 使用 Composer 创建 Symfony 项目

php - 带有 php 和 ssl 的本地主机服务器

php - 有没有办法用表格上传 youtube 视频?

php - 如何根据 PHP 数据库中的结果在 jQuery 日期选择器上禁用一周中的某些天

symfony - 用作 Symfony 参数的非标量 ENV

php - Symfony2 中的 CollectionType 验证

php - Symfony 2 - 使用子实体创建表单并上传文件

php - 在 Goutte 中发送具有相同参数名称的发布请求

具有多个变量组件的 PHP MySQL 语句

php - 测量网站上的在线时间