Як використовувати Serializer

Дата оновлення перекладу 2022-12-23

Як використовувати Serializer

Symfony надає Serializer для серіалізації/десеріалізації в та з об'єктів та різних форматів (наприклад, JSON або XML). До його використаня, прочитайте документи компонента Serializer, який надає вам деякі інструменти, які ви можете використовувати для вирішення ваших задач.

Установка

У додатках, що використовують Symfony Flex , виконайте цю команду, щоб встановити пакет Symfony serializer перед його використанням:

1
$ composer require symfony/serializer-pack

Використання сервісу Serializer

Піся підключення, сервіс серіалізатора може бути впроваджений у будь-який сервіс, де вам це потрібно, або він може бути використаний у контролері:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/Controller/DefaultController.php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Serializer\SerializerInterface;

class DefaultController extends AbstractController
{
    public function index(SerializerInterface $serializer)
    {
        // продовжуйте читати для прикладу використання
    }
}

Або ви можете використати фільтр Twig serialize у шаблоні:

1
{{ object|serialize(format = 'json') }}

Див. довідник twig, щоб дізнатися більше інформації.

Додавання нормалізаторів та кодувальників

Після підключення, сервіс serializer буде доступний у контейнері. Він постачається з набором корисних кодувальників та нормалізаторів .

Включені кодувальники, які підтримують наступні формати:

А також наступні нормалізатори:

Інші вбудовані нормалізатори та користувацькі нормалізатори та/або кодувальники також можна завантажити, тегувавши їх як serializer.normalizer та serializer.encoder . Також можливо встановити пріоритет тегу для того, щоб вирішити порядок співствалення.

Caution

Не забувайте завантажувати DateTimeNormalizer при серіалізації класів DateTime або DateTimeImmutable для уникнення надмірного використання пам'яті та розголошення внутрішніх деталей.

Контекст Serializer

Serializer може визначати контекст для контролю (де)серіалізації джерел. Цей контекст передається всім нормалізаторам. Наприклад:

  • DateTimeNormalizer використовує ключ datetime_format у форматі дати та часу;
  • AbstractObjectNormalizer uses preserve_empty_objects to represent empty objects as {} instead of [] in JSON.
  • Serializer uses empty_array_as_object to represent empty arrays as {} instead of [] in JSON.

Ви можете передати контекст наступним чином:

1
2
3
4
5
6
7
$serializer->serialize($something, 'json', [
    DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s',
]);

$serializer->deserialize($someJson, Something::class, 'json', [
    DateTimeNormalizer::FORMAT_KEY => 'Y-m-d H:i:s',
]);

Ви також можете сконфігурувати контекст за замовчуванням через конфігурацію фреймворку:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
# config/packages/framework.yaml
framework:
    # ...
    serializer:
        default_context:
            enable_max_depth: true
            yaml_indentation: 2

6.2

Опція конфігурації відступу YAML була представлена в Symfony 6.2.

Ви також можете вказати контекст для кожної властивості окремо:

  • Annotations
  • Attributes
  • YAML
  • XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace App\Model;

use Symfony\Component\Serializer\Annotation\Context;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

class Person
{
    /**
     * @Context({ DateTimeNormalizer::FORMAT_KEY = 'Y-m-d' })
     */
    public $createdAt;

    // ...
}

Використайте опції, щоб вказати контекст конкретно для нормалізації або денормалізації:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace App\Model;

use Symfony\Component\Serializer\Annotation\Context;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

class Person
{
    #[Context(
        normalizationContext: [DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'],
        denormalizationContext: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339],
    )]
    public $createdAt;

    // ...
}

Ви також можете обмежити використання контексту деяких груп:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace App\Model;

use Symfony\Component\Serializer\Annotation\Context;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

class Person
{
    #[Groups(['extended'])]
    #[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
    #[Context(
        context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
        groups: ['extended'],
    )]
    public $createdAt;

    // ...
}

Атрибут/анотація можуть повторюватися в одній властивості стільки разів, скільки потрібно. Контекст без групи завжди застосовується першим. Потім контекст для груп, що співпали, зливається у наданому порядку.

Використання будівників контексту

6.1

Будівники контексту були представлені в Symfony 6.1.

Щоб визначити контекст (де)серіалізації, ви можете викоритати "будівники контексту", які є обʼєктами, що допомагають вам створювати цей контекст, надаючи автозаповнення, валідацію та документацію:

1
2
3
4
use Symfony\Component\Serializer\Context\Normalizer\DateTimeNormalizerContextBuilder;

$contextBuilder = (new DateTimeNormalizerContextBuilder())->withFormat('Y-m-d H:i:s');
$serializer->serialize($something, 'json', $contextBuilder->toArray());

Кожний нормалізатор/кодувальник має вій повʼязаний будівник контексту . Щоб створити складніший контекст (де)серіалізації, ви можете зробити з них ланцюг, використовуючи метод withContext():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Symfony\Component\Serializer\Context\Encoder\CsvEncoderContextBuilder;
use Symfony\Component\Serializer\Context\Normalizer\ObjectNormalizerContextBuilder;

$initialContext = [
    'custom_key' => 'custom_value',
];

$contextBuilder = (new ObjectNormalizerContextBuilder())
    ->withContext($initialContext)
    ->withGroups(['group1', 'group2']);

$contextBuilder = (new CsvEncoderContextBuilder())
    ->withContext($contextBuilder)
    ->withDelimiter(';');

$serializer->serialize($something, 'csv', $contextBuilder->toArray());

Ви також можете створити власних будівників контексту, щоб мати автозаповнення, валідацію та документацію для ваших користувацьких значень контексту.

Використання групових анотацій серіалізації

Ви можете додати атрибути #[Groups] до вашого класу:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Entity/Product.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;

#[ORM\Entity]
class Product
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    #[Groups(['show_product', 'list_product'])]
    private $id;

    #[ORM\Column(type: 'string', length: 255)]
    #[Groups(['show_product', 'list_product'])]
    private $name;

    #[ORM\Column(type: 'integer')]
    #[Groups(['show_product'])]
    private $description;
}

Тепер ви можете обирати, які групи використовувати при серіалізації:

1
2
3
4
5
6
7
use Symfony\Component\Serializer\Context\Normalizer\ObjectNormalizerContextBuilder;

$context = (new ObjectNormalizerContextBuilder())
    ->withGroups('show_product')
    ->toArray();

$json = $serializer->serialize($product, 'json', $context);

Tip

Значення ключа groups може бути одним рядком або їх масивом.

На додаток до анотації @Groups, компонент Serializer також підтримує файли YAML або XML. Ці файли автоматично завантажуються при збереженні в одній з наступних локацій:

  • Всі файли *.yaml і *.xml в каталозі config/serializer/.
  • Файл serialization.yaml або serialization.xml в каталозі пакету Resources/config/;
  • Всі файли *.yaml і *.xml в каталозі пакету Resources/config/serialization/.

Використання вкладених атрибутів

Щоб мапувати вкладені властивості, використайте конфігурацію SerializedPath, щоб визначити їх шляхи, використовуючи валідний синтаксис PropertyAccess:

  • Annotations
  • Attributes
  • YAML
  • XML
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace App\Model;

use Symfony\Component\Serializer\Annotation\SerializedPath;

class Person
{
    /**
     * @SerializedPath("[profile][information][birthday]")
     */
    private string $birthday;

    // ...
}

6.2

Опція конфігурування SerializedPath була представлена в Symfony 6.2.

Використовуючи конфігурацію вище, денормалізація з нормалізатором, обізнаним про метадані, запише поле birthday з $data в обʼєкт Person :

1
2
3
4
5
6
7
8
9
$data = [
    'profile' => [
        'information' => [
            'birthday' => '01-01-1970',
        ],
    ],
];
$person = $normalizer->denormalize($data, Person::class, 'any'); 
$person->getBirthday(); // 01-01-1970

При використанні анотацій або атрибутів, SerializedPath може бути або встановлено у властивості, або в асоційованому методі _getter_. SerializedPath не може бути використано у комбінації з SerializedName для тієї ж властивості.

Конфігурація кешу метаданих

Метадані для серіалізатора автоматично кешуються для покращення роботи додатку. За замовчуванням, серіалізатор використовує пул кешу cache.system, який конфігурується з використанням опції cache.system .

Підключення перетворювача імен

Використання сервісу конвертера імен може бути визначене в конфігурації з використанням опції name_converter .

Вбудований конвертер імен CamelCase у snake_case може бути підключено, використовуючи значення serializer.name_converter.camel_case_to_snake_case:

  • YAML
  • XML
  • PHP
1
2
3
4
5
# config/packages/framework.yaml
framework:
    # ...
    serializer:
        name_converter: 'serializer.name_converter.camel_case_to_snake_case'

Поглиблене використання Serializer

Платформа API надає API-систему, яка підтримує наступні формати:

Вона вбудована над фреймворком Symfony та її компонентом Serializer. Вона надає користувацькі нормалізатори та кодувальники, користувацькі метадані та систему кешування.

Якщо ви хочете скористатися перевагами повної потужності компонента Symfony Serializer, подвіться на те, як працює цей пакет.