Symfony Advent Calendar 2022の2日目です。

ずっと気になっていたSymfony Serializerを使ってみました。

試したバージョンはSymfony 6.1.7です。

Symfony6.1からSymfony ProfilerにSerializerのメニューが増えました!!!

collect_serializer_data: trueにすると、有効にできます!

# config/packages/web_profiler.yaml

when@dev:
    framework:
        profiler:
            collect_serializer_data: true   # default false

Serialize, Normalize, Encodeの関係

どのパターンがSerializeでNormalizeなんだっけ?ってなるので以下にまとめました。

Serialize = Normalize + Encode

  • Normalize: Object → Array
  • Encode: Array → Format(JSON)
  • Serialize: Object → Format(JSON)

Deserialize = Decode + Denormalized

  • Decode: Format(JSON) → Array
  • Denormalized: Array → Object
  • Deserialize: Format(JSON) → Object

動作確認

Normalize/Denormalized

Object → Arrayにノーマライズする

  $object = new Project();
  $object->setName('project-A');
  $array = $this->normalizer->normalize($object, 'array'); // ['name' => 'project-A']

Array → Objectにデノーマライズする

  $array = ['name' => 'project-A'];
  $object = $this->denormalizer->denormalize($array, Project::class, 'array'), // object

Encode/Decode

Array → Format(JSON)にエンコードする

  $array = ['name' => 'project-A'];
  $json = $this->encoder->encode($array, 'json')  // '{"name":"project-A"}'

Format(JSON) → Arrayにデコードする

  $json = '{"name":"project-A"}';
  $array = $this->decoder->decode($json, 'json'), // ['name' => 'project-A']

Serialize/Deserialize

Object → Format(JSON)にシリアライズする

  $object = new Project();
  $object->setName('project-A');
  $json = $this->serializer->serialize($object, 'json'); // '{"name":"project-A"}'

Format(JSON) → Objectにデリアライズする

  $json = '{"name":"project-A"}';
  $object = $this->serializer->deserialize($json, Project::class, 'json') // object

ちなみに

以下コードのように、各InterfaceをDIして動作確認をしていたんですが、formatなどを見て「JsonEncoderを使う」「ObjectNormalizerを使う」とか決まってるみたいでした。

use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\SerializerInterface;

class SymfonySerializerTestController extends AbstractController
{
    public function __construct(
        private readonly SerializerInterface $serializer,
        private readonly EncoderInterface $encoder,
        private readonly DecoderInterface $decoder,
        private readonly NormalizerInterface $normalizer,
        private readonly DenormalizerInterface $denormalizer,
    ) {
    }

Symfony Profiler > Serializer

serializeの例 deserializeの例 normalizeの例 denormalizeの例 encodeの例 decodeの例

明日は @bezeklik さんの記事ですー!EasyAdminについてよくわかってないので楽しみです!!!

参考