Routes

Route attributes

Start with fixed paths. Each attribute maps one URL path to one method, and the name makes the route easy to reference later:

namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class BlogController { #[Route("/", name: "app_home")] public function home(): Response { return new Response("Home"); } #[Route("/about", name: "app_about")] public function about(): Response { return new Response("About"); } }

The path /about matches only that exact address. Dynamic parts arrive in the next section.

Parameters {slug}

Placeholders make one method serve many addresses. The placeholder {slug} matches any single part of the path, and Symfony passes the matched text into the argument with the same name:

namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class PostController { #[Route("/post/{slug}", name: "app_post")] public function show(string $slug): Response { return new Response("Post: " . $slug); } }

A request for /post/hello-world calls show with the slug set to hello-world.

Requirements

Placeholders accept anything by default, including values your method cannot use. A requirement narrows the match with a regular expression, so only digits reach the method below:

namespace App\Controller; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; class PostByIdController { #[Route("/post/{id}", name: "app_post_id", requirements: ["id" => "\d+"])] public function byId(int $id): Response { return new Response("Post id: " . $id); } }

Letters and dashes no longer match, and such addresses fall through to a 404.

Route names

Names never appear in the browser address bar. They label routes for redirects and templates, so renaming a path never breaks the code that points to it:

namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; class OldController extends AbstractController { public function old(): Response { return $this->redirectToRoute("app_home"); } }

Prefix names with app_ to avoid clashes with bundle routes.

Next: Controllers

Article author: Arthur Isaev

Banner image