New in Symfony 6.3: Query Parameters Mapper
May 4, 2023 • Published by Javier Eguiluz
Symfony 6.3 is backed by:
Warning: This post is about an unsupported Symfony version. Some of this information may be out of date. Read the most recent Symfony Docs.
Contributed by
Ruud Kamphuis
in #49134.
In Symfony 6.3 we introduced a feature to map request data into typed objects
using the #[MapRequestPayload]
and #[MapQueryString]
attributes. However,
sometimes you want to map individual request data to specific controller arguments.
Symfony has allowed to map route parameters to controller arguments since its
first version. In Symfony 6.3 you will also be able to map query string parameters
to specific controller arguments. To do so, use the new #[MapQueryParameter]
attribute:
1 2 3 4 5 6 7 8 9
#[Route(path: '/', name: 'admin_dashboard')]
public function indexAction(
#[MapQueryParameter] array $ids,
#[MapQueryParameter] string $firstName,
#[MapQueryParameter] bool $required,
#[MapQueryParameter] int $age,
#[MapQueryParameter] string $category = '',
#[MapQueryParameter] ?string $theme = null,
)
If the query string of the incoming request is /?ids[]=1&ids[]=2&firstName=Ruud&required=3&age=123
,
this code will make the controller arguments to have these values:
1 2 3 4 5 6
$ids = ['1', '2']
$firstName = "Ruud"
$required = false
$age = 123
$category = ''
$theme = null
The #[MapQueryParameter]
attribute makes the conversion of the query string
parameter(which is always a string) into the proper PHP type according to the
types of your controller arguments (it's similar to calling
$request->query->getInt('...')
, $request->query->getAlpha('...')
, etc.
but automated by Symfony).
For more advanced use cases, you can use the filter
option of the attribute
to validate the data type details:
1 2 3 4 5 6 7
// this ensures that the array only contains integer values
#[MapQueryParameter(filter: \FILTER_VALIDATE_INT)]
array $ids
// this ensures that the string follows some specific pattern
#[MapQueryParameter(filter: \FILTER_VALIDATE_REGEXP, options: ['regexp' => '/^\w++$/'])]
string $name
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
Give me a way to map request headers to be deserialized now and I imagine you’ll have hit every point (and that would be awesome for APIs that do challenges based on headers).
If I don't pass "page" in the query string, I get:
Controller "App\Controller\MyController::index" requires that you provide a value for the "$page" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.
So, apart from the wrong wording in the error (the "because" is non-sense, and "non optional" should be written as "non-optional", it just doesn't work.