The Routing component provides an impressive list of features to map incoming URLs to your application code. Symfony 7.3 pushes it even further with a set of new features that improve developer experience.

Improved Route Attribute

Jérôme Tamarelle
Contributed by Jérôme Tamarelle in #60081

In Symfony, controllers often extend the base controller class to access shortcut methods and enable features like service argument resolving. However, this isn't mandatory: you can also use the #[AsController] attribute to enable those features without inheritance:

1
2
3
4
5
6
7
8
9
10
11
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;

#[AsController]
class DefaultController
{
    // ...
}

Symfony 7.3 simplifies this further. When you add the #[Route] attribute to a class or any of its methods, it's now automatically treated as a controller and service argument resolution is enabled. That means you no longer need to add #[AsController] separately:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace App\Controller;

  use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpKernel\Attribute\AsController;
  use Symfony\Component\Routing\Attribute\Route;

- #[AsController]
  class DefaultController
  {
      #[Route('/', name: 'homepage', methods: ['GET'])]
      public function index(): Response
      {
          // ...
      }
  }

Route Aliases in Attributes

Damien Fernandes
Contributed by Damien Fernandes in #58819

Route aliasing lets you define multiple names for a single route. This is especially useful for backward compatibility when renaming routes. In Symfony 7.3, this feature is now also available directly in PHP attributes via the alias option:

1
2
3
4
5
#[Route('/product/{id}', name: 'product_show', alias: ['product', 'product_detail'])]
public function productShow(int $id): Response
{
    // ...
}

New Requirement Pattern

Jérôme Tamarelle
Contributed by Jérôme Tamarelle in #59922

The Routing component includes a Requirement PHP enum that provides a collection of common regular expressions that you can use as route parameter requirements:

1
2
3
4
use Symfony\Component\Routing\Requirement\Requirement;

#[Route('/blog/{page}', requirements: ['page' => Requirement::DIGITS]), name: 'blog_list']
public function list(int $page): Response

In Symfony 7.3 we're adding a new regular expression called MONGODB_ID to validate MongoDB ObjectIDs in hexadecimal format, commonly used in Doctrine ODM.

Route Parameter Aliases

Eltharin
Contributed by Eltharin in #59904

Parameter conversion allows you to map route parameters to PHP objects, typically Doctrine entities. For example, a route like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// src/Controller/BlogController.php
namespace App\Controller;

use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class UserController extends AbstractController
{
    // ...

    #[Route('/user/{id:user}', name: 'user_show')]
    public function show(User $user): Response
    {
        // 'id' is the route parameter
        // 'id:user' tells Symfony to convert it into a User object
        // using the ID value in the database query
    }
}

However, when using multiple parameters of the same name, conflicts arise:

1
#[Route('/search-book/{name:author}/{name:category}')]

In this example, the route tries to define two mappings using the same name parameter. This isn't allowed because the route ends up declaring name twice. In Symfony 7.3, we're improving this feature thanks to route parameter aliases:

1
#[Route('/search-book/{authorName:author.name}/{categoryName:category.name}')]

Here, authorName and categoryName are the actual route parameters, and Symfony maps them to the correct entities by using their aliases. This avoids collisions and improves clarity in both routing and controller logic.

Published in #Living on the edge