Symfony ParamConverter
is a very powerful feature provided by the Symfony framework that allows you to automatically convert route parameters into objects or other data types.Typically is declared as an Event Listener and is triggered in each incoming HTTP Request.
Examples of how you can use Symfony ParamConverter
:
Entity Conversion:
Suppose you have an entity called Product with an identifier productId
. You can use ParamConverter
to automatically fetch the Product object from the database based on the productId
passed in the route parameter.
use App\Entity\Product;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* @Route("/product/{productId}")
* @ParamConverter("product", class="App\Entity\Product")
*/
public function showProduct(Product $product)
{
// $product will contain the Product object based on the productId
// ...
}
In this example, Symfony ParamConverter
simplifies the process of fetching an entity object based on a route parameter. The @ParamConverter
annotation is used to specify the conversion. The class option specifies the target entity class to which the parameter should be converted.
Additionally, you can customize the query used to retrieve the entity by adding additional options. For example, you can specify a different database column to match the route parameter by using the options option:
/**
* @Route("/product/{slug}")
* @ParamConverter("product", class="App\Entity\Product", options={"mapping": {"slug": "name"}})
*/
public function showProduct(Product $product)
{
// The 'slug' route parameter will be used to fetch the Product object by the 'name' column
// ...
}
Type Conversion:ParamConverter
can also be used to convert route parameters into specific data types other than entities. For example, let's say you have a route parameter date that represents a date string, and you want to convert it into a DateTime
object.
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use DateTime;
/**
* @Route("/event/{date}")
* @ParamConverter("eventDate", converter="datetime", options={"format": "Y-m-d"})
*/
public function showEvent(DateTime $eventDate)
{
// $eventDate will contain the DateTime object based on the date parameter
// ...
}
In this example, the @ParamConverter
annotation uses the converter option to specify the built-in datetime
converter.
The options option allows you to provide additional configuration for the converter. In this case, the format option is used to specify the expected format of the date string in the route parameter. The datetime
converter will then parse the parameter value and convert it into a DateTime
object automatically.
You can use various other built-in converters provided by Symfony, such as bool, int, float,
etc., to convert route parameters into different data types.
Custom Converter:
You can also create your own custom ParamConverter
to perform a specific conversion logic. For example, let's say you want to convert a route parameter userId
into a User object by fetching it from a custom service.
use App\Service\UserService;
use App\Entity\User;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* @Route("/user/{userId}")
* @ParamConverter("user", converter="app.user_converter")
*/
public function showUser(User $user)
{
// $user will contain the User object based on the userId
// ...
}
In your custom converter app.user_converter
, you can define the conversion logic using the ParamConverterInterface
.
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
use Symfony\Component\HttpFoundation\Request;
use App\Service\UserService;
use App\Entity\User;
class UserConverter implements ParamConverterInterface
{
private $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function apply(Request $request, ParamConverter $configuration)
{
$userId = $request->attributes->get('userId');
$user = $this->userService->getUserById($userId);
$request->attributes->set($configuration->getName(), $user);
return true;
}
public function supports(ParamConverter $configuration)
{
return $configuration->getName() === 'user';
}
}
In my case, I use a custom ParamConverter
set as an event listener, to convert DTOs in all Api Endpoints. For more on this go to my Article: Using DTOs in PHP Symfony
Thanks to this powerful feature, I can save tons of hours of development. Definitely, this ParamConverter
is one of my favorite features in Symfony Framework.