webkenny webkenny - 4 months ago 10x
PHP Question

Use cases for generated URLs in Symfony2?

Coming from a straight PHP and Drupal background, I am recently learning the Symfony2 framework. Currently I am in the routing chapter of the book. This is probably a simple question.

What are some real world use cases for why one would want to generate URLs in a Symfony app? I understand the code but I'm having a bit of trouble determining its practical applications.

I'm referring to this section should you need a refresher.

As always, thank you!

P.S. Symfony is amazing. :)


Basically, you need to generate a URL whenever you need to link to anywhere in your application.

Let's say that you have an application that needs to manage some users. This means that you will probably have URLs like /user/create, /user/edit/(user id) and /user/remove/(user id).

Whenever you display a link to edit a user you need to know on what URL you can find the page that allows you to edit a user. So you need to link to /user/edit/(user id). One solution would be to have this as a fixed link so that in your code you could just write

<a href="/user/edit/<?= $currentUser->getId() ?>">edit this user</a>

But what if you want to change this URL scheme? Let's say someone is unhappy with the term "user", after all the humans managed by this system are not only users, they are actually "person"s! So now you need to change all the URLs containing "user". Probably there are quite a few places in your app where you have had to hardcode these URLs and now you will need to find and change all of them. Eugh.

But fear not, for Symfony routing comes to the rescue!

Instead of hardcoding these URLs, we can simply let the Symfony router generate them for us. This means that we first need to tell Symfony which routes we have, e.g. by adding the following YAML code to our routes config file:

  path:     /user/edit/{userId}
  defaults: { _controller: AppBundle:User:edit }
      userId:  \d+

This tells our application "Okay, whenever somebody requests a page that looks like /user/edit/{userId}, then you need to call the editAction method in our UserController class in the AppBundle namespace and you need to pass the userId as a parameter. Oh, and also you should only call the controller if userId is a valid integer with at least one number."

So this is how Symfony knows how to map URLs to controllers. But the goodness that comes along with it is that we can use this information for the reverse way as well.

Usually, in our application we do not really care about what the URL looks like for a certain action we want to perform. All we know is that when clicking a certain link, then the browser should jump to a page that allows me to edit a user. And since we just defined a route that takes us right there, we can have Symfony generate the correct URL to achieve just that.

So in your view you can now discard the hardcoded URL from earlier and instead replace it with a route generated by the Symfony router:

<a href="<?= $view['router']->generate('user_edit', ["userId" => $currentUser->getId()]) ?>">edit this user</a>

Now whenever you need to change what the URL actually looks like all you need to do is edit your routing config and not a lot of separate views.