简体   繁体   中英

Set url parameter in route (Symfony 2.6)

So, lets assume i got this showAction() in my DisplayController.php :

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

Usually, the following route links to this action:

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

So, when I request my-website.com/display/product/A , everything works as intended.

However, now I need to implement a quicklink which requires me to skip the type argument which looks like my-website.com/specific-product which is supposed to link to my-website.com/display/product/specific-product . The route i created for that looks like that:

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

The specific error messages is 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).

However, that doesn't work since I'm required to add a $type in order for it to work. I could create a new showSpecificProductAction , but I don't want to do that since both functions basically do the same. So I was wondering if i can "set" variables within routes so I can basically only make $slug an actual variable without editing the showAction() itself?

在Controller动作中,将功能更改为public function showAction($type='product', $slug)

Do not search for easier/shorter solutions. Make thing correctly and you won't have problems in future.

First, define your routing logic/aim. If you want a short url to redirect you to a full page, than do exactly this. You could do this in yaml right away with:

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

If you don't know the default type value, just create new action in controller, find the value and redirect from controller providing this value and using proper HTTP code. Such redirects are good for SEO as well:

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...
}

If you DO need both urls to work, just create 2 routes configuration and 2 actions. But since they have common logic, create a private method in controller, which will do the logic for both. This is what OOP is all about:

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', [...]);
}

Think of a logic first, then separate logical parts (using route/controller/action). This is what it is all about. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM