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
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
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
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
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.
Sweet! Shouldn't "When you add the #[Route] attribute to a class," be "When you add the #[Route] attribute to a class or method"? While the Route attribute can be added to either a class or a method, the example shows a method.
You are right Tac! We just reworded the post to mention that. Thanks!
Just a small typo in the "New requirement pattern" section : the closing parenthesis for the
Route
attribute should be after thename
parameter :)Really nice improvements anyway !
Is automatic treatment as controller gonna be back ported to Symfony 6.4?