Как создать свой пользовательский конструктор контекста
Дата обновления перевода 2024-07-27
Как создать свой пользовательский конструктор контекста
Компонент Serializer использует нормализаторы и кодировщики для преобразования любых данных в любую структуру данных (например, JSON). Процесс сериализации может быть сконфигурирован благодаря контексту сериализации , который может быть создан благодаря конструкторам контекста .
Каждый встроенный нормализатор/кодировщик имеет свой соответствующий конструктор контекста. Однако вы вы можете захотеть создать собственный конструктор контекста для ваших настраиваемых нормализаторов.
Создание конструктора контекста
Представим, что вы хотите по-другому обрабатывать денормализацию дат, если они
поступают из унаследованной системы, преобразуя даты в null
, если сериализованное
значение 0000-00-00
. Для этого сначала нужно создать свой нормализатор:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
// src/Serializer/ZeroDateTimeDenormalizer.php
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
final class ZeroDateTimeDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface
{
use DenormalizerAwareTrait;
public function denormalize($data, string $type, string $format = null, array $context = []): mixed
{
if ('0000-00-00' === $data) {
return null;
}
unset($context['zero_datetime_to_null']);
return $this->denormalizer->denormalize($data, $type, $format, $context);
}
public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
{
return true === ($context['zero_datetime_to_null'] ?? false)
&& is_a($type, \DateTimeInterface::class, true);
}
}
Теперь вы можете приводить нулевые даты к null
при денормализации:
1 2
$legacyData = '{"updatedAt": "0000-00-00"}';
$serializer->deserialize($legacyData, MyModel::class, 'json', ['zero_datetime_to_null' => true]);
Теперь, чтобы избежать необходимости помнить об этом специфическом ключе контекста zero_date_to_null
,
можно создать специальный конструктор контекста:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// src/Serializer/LegacyContextBuilder
namespace App\Serializer;
use Symfony\Component\Serializer\Context\ContextBuilderInterface;
use Symfony\Component\Serializer\Context\ContextBuilderTrait;
final class LegacyContextBuilder implements ContextBuilderInterface
{
use ContextBuilderTrait;
public function withLegacyDates(bool $legacy): static
{
return $this->with('zero_datetime_to_null', $legacy);
}
}
И наконец, используйте его для создания контекста сериализации:
1 2 3 4 5 6 7
$legacyData = '{"updatedAt": "0000-00-00"}';
$context = (new LegacyContextBuilder())
->withLegacyDates(true)
->toArray();
$serializer->deserialize($legacyData, MyModel::class, 'json', $context);