我需要我的网站可以通过 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
)。我想更改此设置,以便它适用于我的整个 MywebsiteBlogBundle。
在我的自定义加载器中,我想测试如下内容:
$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/