Новое в Symfony 6.3 — Преобразование целевых значений

Источник: «New in Symfony 6.3: Targeted Value Resolvers»
Symfony 6.3 вводит новый атрибут ValueResolver для явного выбора преобразователя аргументов, для использования в аргументах контроллера.

В Symfony преобразователи значений аргументов позволяют вводить определённые значения в аргументы контроллеров. Например, если вы указываете какой-либо аргумент контроллера с классом Request из HttpFoundation, Symfony внедряет объект, представляющий текущий запрос.

Symfony предоставляет множество встроенных преобразователей для внедрения сервисов, сеанса, значений UID, значений PHP по умолчанию и т.д. В Symfony 6.3 мы улучшаем эту функцию, чтобы сделать её более мощной. Во-первых, мы вводим новый атрибут ValueResolver для явного выбора используемого преобразователя.

Рассмотрим следующий пример:

// src/Controller/SessionController.php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;

class SessionController
{
#[Route('/')]
public function __invoke(SessionInterface $session = null): Response
{
// ...
}
}

Symfony будет вызывать все встроенные преобразователи аргументов по приоритету, пока один из них не предоставит значение для этого аргумента. В этом примере SessionValueResolver (приоритет 50) будет вызывать перед DefaultValueResolver (приоритет -100). Вот почему аргумент $session будет содержать либо текущий объект Session, либо значение null.

Если вы уверены, что в вашем приложении всегда будет сессия, то можно сделать так:

// ...
use Symfony\Component\HttpKernel\Attribute\ValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\SessionValueResolver;

class SessionController
{
#[Route('/')]
public function __invoke(
#[ValueResolver(SessionValueResolver::class)]
SessionInterface $session
): Response
{
// ...
}
}

Новый атрибут ValueResolver позволяет явно указать Symfony, какой преобразователь следует использовать для получения значения этого аргумента. Для удобства имена всех строенных распознавателей — это их FQCN (например, SessionValueResolver::class).

В дополнение к этому мы добавили ещё один новый атрибут AsTargetedValueResolver для создания явного преобразователей, которые можно вызвать только явно. Рассмотрим следующий преобразователь аргументов, который преобразует значения id бронирования в объекты Booking:

// src/ValueResolver/IdentifierValueResolver.php
namespace App\ValueResolver;

use Symfony\Component\HttpKernel\Attribute\AsTargetedValueResolver;
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;

#[AsTargetedValueResolver('booking_id')]
class BookingIdValueResolver implements ValueResolverInterface
{
// ...
}

Вместо того чтобы разрешить Symfony вызывать этот преобразователь для всех аргументов контроллеров, новый атрибут #[AsTargetedValueResolver] говорит Symfony использовать этот преобразователь только в том случае, если он вызывается явно. Поэтому он будет использоваться только в таких случаях:

// ...
use Symfony\Component\HttpKernel\Attribute\ValueResolver;

class BookingController
{
#[Route('/booking/{id}')]
public function show(#[ValueResolver('booking_id')] Booking $booking): Response
{
// ...
}
}

Дополнительные материалы

Предыдущая Статья

Архитектурный плагин Pest

Следующая Статья

Расширение перечислений PHP 8.1 с помощью атрибутов