在路由中设置url参数(Symfony 2.6)

时间:2016-06-20 13:33:14

标签: php symfony

所以,我们假设我在showAction()中得到了这个DisplayController.php

/**
 * @param $type
 * @param $slug
 * @return \Symfony\Component\HttpFoundation\Response
 */
public function showAction($type, $slug)
{ 
    ...
}

通常,以下路由链接到此操作:

my_bundle_display_show:
    pattern: /display/{type}/{slug}
    defaults: { _controller: MyFunnyBundle:Display:show }

因此,当我请求my-website.com/display/product/A时,一切都按预期工作。

但是,现在我需要实现一个快速链接,要求我跳过type参数,该参数看起来像my-website.com/specific-product,应该链接到my-website.com/display/product/specific-product。我为此创建的路线如下:

my_bundle_display_show_specific_product:
    pattern: /{slug}
    defaults: { _controller: MyFunnyBundle:Display:show }
    requirements:
        slug: "specific-product"
    defaults:
        type: "product"

具体的错误消息是Controller "MyBundle\Controller\DisplayController::showAction()" requires that you provide a value for the "$type" argument (because there is no default value or because there is a non optional argument after this one).

但是,这不起作用,因为我需要添加$type才能使其正常工作。我可以创建一个新的showSpecificProductAction,但我不想这样做,因为这两个函数基本上都是一样的。所以我想知道我是否可以在路线中“设置”变量,这样我基本上只能将$slug变为实际变量,而无需编辑showAction()本身?

2 个答案:

答案 0 :(得分:0)

在“控制器”操作中,将功能更改为 public function showAction($type='product', $slug)

答案 1 :(得分:0)

不要搜索更简单/更短的解决方案。正确地做事,将来你不会有问题。

首先,定义您的路由逻辑/目标。如果您想要一个简短的网址将您重定向到一个完整的页面,那么这样做。你可以马上用yaml做到这一点:

my_bundle_display_show_specific_product:
    path: /{slug}/
    defaults:
        _controller: FrameworkBundle:Redirect:redirect
        route: my_bundle_display_show
        permanent: true
        type: "some default value"

如果您不知道默认类型值,只需在控制器中创建新操作,找到值并从控制器重定向,提供此值并使用正确的HTTP代码。这样的重定向对SEO也有好处:

public function actionOne($slug) {
    $type = ... // find out the type
    return $this->redirectToRoute('actionTwo', ['type' => $type, 'slug' => $slug], 301);
}

public function actionTwo($type, $slug) {
    // do some stuff...
}

如果您需要两个网址都可以工作,只需创建2个路由配置和2个操作。但由于它们具有通用逻辑,因此在控制器中创建一个私有方法,这将为两者执行逻辑。这就是OOP的全部内容:

public function actionOne($slug) {

    $type = ... // find out the type

    return $this->renderProduct($type, $slug);
}

public function actionTwo($type, $slug) {
    return $this->renderProduct($type, $slug);
}

private function renderProduct($type, $slug) {
     return $this->render('view', [...]);
}

首先考虑逻辑,然后分离逻辑部分(使用路径/控制器/动作)。这就是它的全部意义。祝你好运!