如何创建自定义上下文构建器
Serializer 组件的序列化过程可以通过序列化上下文进行配置,而序列化上下文可以通过上下文构建器来构建。
每个内置的规范化器/编码器都有其相关的上下文构建器。但是,您可能希望为您的自定义规范化器创建自定义上下文构建器。
创建一个新的上下文构建器
假设您想以不同的方式处理日期反规范化,如果日期来自遗留系统,则当序列化值为 0000-00-00
时,将日期转换为 null
。为此,您首先必须创建您的规范化器
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);
这项工作,包括代码示例,根据 Creative Commons BY-SA 3.0 许可协议获得许可。