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

Дата оновлення перекладу 2025-01-16

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

Symfony надає серіалізатор для перетворення структур даних з
одного формату на PHP-об'єкти і навпаки.

Це найчастіше використовується при створенні API або спілкуванні зі
сторонніми API. Серіалізатор може перетворити вхідний JSON-запит на PHP-об'єкт, який споживається вашим додатком. Потім, при генеруванні відповіді, ви можете використовувати серіалізатор для перетворення
PHP-об'єктів назад у відповідь JSON.

Його також можна використовувати, наприклад, для завантаження даних
конфігурації CSV як PHP-об'єктів, або навіть для перетворення між
форматами (наприклад, YAML на XML).

Установка

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

1
$ composer require symfony/serializer-pack

Note

Пакет серіалізатора також встановлює деякі часто використовувані необов'язкові
залежності компонента Serializer. При використанні цього компонента
поза межами фреймворку Symfony, ви можете почати з пакета symfony/serializer
і встановити необов'язкові залежності, якщо вони вам потрібні.

See also

Популярною альтернативою компоненту Symfony Serializer є стороння
бібліотека JMS serializer.

Серіалізація обʼєкта

Для цього прикладу припустимо, що у вашому проекті існує наступний клас:

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
// src/Model/Person.php
namespace App\Model;

class Person
{
    public function __construct(
        private int $age,
        private string $name,
        private bool $sportsperson
    ) {
    }

    public function getAge(): int
    {
        return $this->age;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function isSportsperson(): bool
    {
        return $this->sportsperson;
    }
}

Якщо ви хочете перетворити об'єкти цього типу на JSON-структуру (наприклад
відправити їх через API-відповідь), отримайте сервіс serializer, використовуючи тип параметра SerializerInterface :

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

use App\Model\Person;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\SerializerInterface;

class PersonController extends AbstractController
{
    public function index(SerializerInterface $serializer): Response
    {
        $person = new Person('Jane Doe', 39, false);

        $jsonContent = $serializer->serialize($person, 'json');
        // $jsonContent містить {"name":"Jane Doe","age":39,"sportsperson":false}

        return JsonResponse::fromJsonString($jsonContent);
    }
}

Перший параметр serialize() є об' єктом, який потрібно серіалізувати, а другий - використовується для вибору відповідного кодувальника (тобто формату), у цьому випадку JsonEncoder.

Tip

Коли ваш клас контролера розширює AbstractController (як у вищенаведеному прикладі), ви можете
спростити свій контролер, використовуючи метод json() для створення JSON-відповіді з об'єкту за допомогою Serializer:

1
2
3
4
5
6
7
8
9
10
class PersonController extends AbstractController
{
    public function index(): Response
    {
        $person = new Person('Jane Doe', 39, false);

        // якщо Serializer недоступний, використовуватиметься json_encode()
        return $this->json($person);
    }
}

Використання Serializer у шаблонах Twig

Ви також можете серіалізувати об'єкти в будь-якому шаблоні Twig за допомогою фільтра
serialize:

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

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

Десеріалізація обʼєкта

API часто також потребують перетворення відформатованого тіла запиту (наприклад, JSON) на об'єкт PHP. Цей процес називається десеріалізація (також відома як "гідратація"):

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

// ...
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;

class PersonController extends AbstractController
{
    // ...

    public function create(Request $request, SerializerInterface $serializer): Response
    {
        if ('json' !== $request->getContentTypeFormat()) {
            throw new BadRequestException('Unsupported content format');
        }

        $jsonData = $request->getContent();
        $person = $serializer->deserialize($jsonData, Person::class, 'json');

        // ... зробити щось з $person та повернути відповідь
    }
}

У цьому випадку, deserialize() потребує трьох параметрів:

  1. Дані, які потрібно розшифрувати
  2. Ім'я класу, до якого буде розшифровано цю інформацію
  3. Назва кодувальника, який використовується для перетворення даних на масив (тобто формат введення)

При надсиланні запиту до цього контролера (наприклад {"first_name":"John Doe","age":54,"sportsperson":true}), серіалізатор створить новий екземпляр Person і встановить властивості у значення з наданого JSON.

Note

За замовчуванням, додаткові атрибути, які не зіставлені з денормалізованим об'єктом, будуть проігноровані компонентом Serializer. Наприклад,
якщо запит до вищенаведеного контролера містить {..., «city»: «Paris"}, поле city буде проігноровано. Ви також можете викликати виключення в цих випадках за допомогою контексту serializer , про який ви дізнаєтеся пізніше.

See also

Ви також можете десеріалізувати дані в існуючий екземпляр об'єкта (наприклад при оновленні даних). Дивіться
Десеріалізація в існуючий об'єкт .

Процес серіалізації: нормалізатори та кодувальники

Серіалізатор використовує двоетапний процес при (де)серіалізації об'єктів:

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

Нормалізатори
Ці класи перетворюють об'єкти на масиви і навпаки. Вони виконують важку роботу, з'ясовуючи, які властивості класу потрібно серіалізувати, яке значення вони мають і яку назву вони повинні мати.
Кодувальники
Кодувальники перетворюють масиви на певний формат і навпаки навпаки. Кожен кодувальник точно знає, як аналізувати та генерувати певний формат, наприклад JSON або XML.

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

Існує декілька нормалізаторів, сконфігурованих у сервісі Serializer за замовчуванням. Найважливішим нормалізатором є ObjectNormalizer. Цей нормалізатор використовує відображення та компонент PropertyAccess для перетворення між будь-яким об'єктом та масивом. Ви дізнаєтеся більше про цей та інші нормалізатори пізніше.

Серіалізатор за замовчуванням також сконфігуровано з деякими кодувальниками, які охоплюють поширені формати, що використовуються HTTP- додатками:

Прочитайте більше про ці кодувальники та їх конфігурацію в Кодувальники Serializer.

Tip

Проект API Platform надає кодувальники для більш просунутих форматів:

Контекст Serializer

Серіалізатор, його нормалізатори та кодувальники конфігуруються за допомогою контексту
серіалізатора
. Цей контекст можна сконфігурувати у декількох місцях:

  • Глобально через конфігурацію фреймворку
  • Під час серіалізації/десеріалізації
  • Для конкретної властивості

Ви можете використовувати всі три варіанти одночасно. Якщо одне і те саме налаштування сконфігуровано в декількох місцях, останнє у списку вище перевизначатиме попереднє (наприклад, налаштування для конкретної властивості перевизначає те, що
сконфігуровано глобально).

Сконфігуруйте контекст за замовчуванням

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

1
2
3
4
5
# config/packages/serializer.yaml
framework:
    serializer:
        default_context:
            allow_extra_attributes: false

Передайте контекст під час серіалізації/десеріалізації

Ви також можете сконфігурувати контекст для одного виклику serialize()/deserialize(). Наприклад, ви можете пропустити властивості властивості зі значенням null лише для одного виклику серіалізатора:

1
2
3
4
5
6
7
8
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;

// ...
$serializer->serialize($person, 'json', [
    AbstractObjectNormalizer::SKIP_NULL_VALUES => true
]);

// наступні викликати до serialize() НЕ пропускатимуть значення null
Використання будівників контексту

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

1
2
3
4
5
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());

See also

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

Сконфігуруйте контекст у конкретній властивості

Нарешті, ви також можете сконфігурувати значення контексту для конкретної властивості об'єкта. Наприклад, для конфігурації формату часу та дати:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/Model/Person.php

// ...
use Symfony\Component\Serializer\Attribute\Context;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

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

    // ...
}

Note

При використанні YAML або XML файли мап повинні бути розміщені в одному з цих місць:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// src/Model/Person.php

// ...
use Symfony\Component\Serializer\Attribute\Context;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;

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

    // ...
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/Model/Person.php

// ...
use Symfony\Component\Serializer\Attribute\Context;
use Symfony\Component\Serializer\Attribute\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 \DateTimeImmutable $createdAt;

    // ...
}

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

Якщо ви повторюєте той самий контекст у декількох властивостях, скористайтеся атрибутом
#[Context] у вашому класі, щоб застосувати цю конфігурацію контексту до всіх властивостей класу :

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

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

#[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
#[Context(
    context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
    groups: ['extended'],
)]
class Person
{
    // ...
}

Серіалізація в або з PHP-масивів

Serializer за замовчуванням також може бути
використано для виконання лише одного кроку двокрокового процесу серіалізації за допомогою відповідного інтерфейсу:

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
29
30
31
32
33
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
// ...

class PersonController extends AbstractController
{
    public function index(DenormalizerInterface&NormalizerInterface $serializer): Response
    {
        $person = new Person('Jane Doe', 39, false);

        // використати normalize(), щоб перетоврити PHP-обʼєкт на масив
        $personArray = $serializer->normalize($person, 'json');

        // ...та denormalize(), щоб перетвортии масив назад на PHP-обʼєкт
        $personCopy = $serializer->denormalize($personArray, Person::class);

        // ...
    }

    public function json(DecoderInterface&EncoderInterface $serializer): Response
    {
        $data = ['name' => 'Jane Doe'];

        // використати encode(), щоб перетворити PHP-масиви на інший формат
        $json = $serializer->encode($data, 'json');

        // ...та decode(), щоб перетворити будь-який формат просто на PHP-масиви (замість обʼєктів)
        $data = $serializer->decode('{"name":"Charlie Doe"}', 'json');
        // $data contains ['name' => 'Charlie Doe']
    }
}

Ігнорування властивостей

ObjectNormalizer нормалізує всі властивості об'єкту та всі
методи, що починаються з get*(), has*(), is*() та can*(). Деякі властивості або методи ніколи не повинні бути серіалізовані. Ви можете
виключити їх за допомогою атрибута #[Ignore]:

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

use Symfony\Component\Serializer\Attribute\Ignore;

class Person
{
    // ...

    #[Ignore]
    public function isPotentiallySpamUser(): bool
    {
        // ...
    }
}

Властивість potentiallySpamUser тепер ніколи не буде серіалізована:

1
2
3
4
5
6
7
8
9
10
11
12
13
use App\Model\Person;

// ...
$person = new Person('Jane Doe', 32, false);
$json = $serializer->serialize($person, 'json');
// $json містить {"name":"Jane Doe","age":32,"sportsperson":false}

$person1 = $serializer->deserialize(
    '{"name":"Jane Doe","age":32,"sportsperson":false","potentiallySpamUser":false}',
    Person::class,
    'json'
);
// значення "potentiallySpamUser" ігнорується

Ігнорування атрибутів з використанням контексту

Ви також можете передати масив імен атрибутів для ігнорування під час виконання за допомогою
опцій контексту ignored_attributes:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;

// ...
$person = new Person('Jane Doe', 32, false);
$json = $serializer->serialize($person, 'json',
[
    AbstractNormalizer::IGNORED_ATTRIBUTES => ['age'],
]);
// $json містить {"name":"Jane Doe","sportsperson":false}

Однак це може швидко призвести до непередбачуваних наслідків, якщо використовувати його надмірно. Див. наступний розділ про групи серіалізації для кращого рішення.

Вибір конкретних властивостей

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

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

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

use Symfony\Component\Serializer\Attribute\Groups;

class Person
{
    #[Groups(["admin-view"])]
    private int $age;

    #[Groups(["public-view"])]
    private string $name;

    #[Groups(["public-view"])]
    private bool $sportsperson;

    // ...
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$json = $serializer->serialize(
    $person,
    'json',
    ['groups' => 'public-view']
);
// $json містить {"name":"Jane Doe","sportsperson":false}

// ви також можете передати масив груп
$json = $serializer->serialize(
    $person,
    'json',
    ['groups' => ['public-view', 'admin-view']]
);
// $json містить {"name":"Jane Doe","age":32,"sportsperson":false}

// або використати спеціальне значення "*" для вибору всіх груп
$json = $serializer->serialize(
    $person,
    'json',
    ['groups' => '*']
);
// $json містить {"name":"Jane Doe","age":32,"sportsperson":false}

Використання контексту серіалізації

Нарешті, ви також можете скористатися опцією контексту attributes для вибору властивостей під час виконання:

1
2
3
4
5
6
7
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
// ...

$json = $serializer->serialize($person, 'json', [
    AbstractNormalizer::ATTRIBUTES => ['name', 'company' => ['name']]
]);
// $json містить {"name":"Dunglas","company":{"name":"Les-Tilleuls.coop"}}

Доступні лише атрибути, які не ігноруються .
Якщо встановлено групи серіалізації, можна використовувати лише атрибути, дозволені цими групами.

Робота з масивами

Серіалізатор може працювати з масивами об'єктів. Серіалізація масивів працює так само, як і серіалізація одного об'єкта:

1
2
3
4
5
6
7
8
9
10
use App\Model\Person;

// ...
$person1 = new Person('Jane Doe', 39, false);
$person2 = new Person('John Smith', 52, true);

$persons = [$person1, $person2];
$JsonContent = $serializer->serialize($persons, 'json');

// $jsonContent містить [{"name":"Jane Doe","age":39,"sportsman":false},{"name":"John Smith","age":52,"sportsman":true}]

Щоб десеріалізувати список об'єктів, до типу параметра потрібно додати []:

1
2
3
4
// ...

$jsonData = ...; // серіалізовані дані JSON з попереднього прикладу
$persons = $serializer->deserialize($JsonData, Person::class.'[]', 'json');

Для вкладених класів ви повинні додати тип PHPDoc до властивості, конструктора або сеттера:

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
// src/Model/UserGroup.php
namespace App\Model;

class UserGroup
{
    /**
     * @param Person[] $members
     */
    public function __construct(
        private array $members,
    ) {
    }

    // або, якщо ви використовуєте сеттер

    /**
     * @param Person[] $members
     */
    public function setMembers(array $members): void
    {
        $this->members = $members;
    }

    // ...
}

Tip

Serializer також підтримує типи масивів, що використовуються у статичному аналізі, такі як list<Person> та array<Person>. Переконайтеся, що встановлено пакети phpstan/phpdoc-parser та phpdocumentor/reflection-docblock (вони є частиною
пакету symfony/serializer-pack).

Десеріалізація з використанням вкладених структур

Деякі API можуть надавати багатослівні вкладені структури, які ви захочете спростити в об'єкти PHP. Наприклад, уявіть собі таку відповідь у форматі JSON:

1
2
3
4
5
6
7
8
9
{
    "id": "123",
    "profile": {
        "username": "jdoe",
        "personal_information": {
            "full_name": "Jane Doe"
        }
    }
}

Можливо, ви захочете серіалізувати цю інформацію в один об'єкт PHP типу:

1
2
3
4
5
6
class Person
{
    private int $id;
    private string $username;
    private string $fullName;
}

Використайте #[SerializedPath], щоб вказати шлях до вкладеної властивості, використовуючи валідний синтаксис PropertyAccess:

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

use Symfony\Component\Serializer\Attribute\SerializedPath;

class Person
{
    private int $id;

    #[SerializedPath('[profile][username]')]
    private string $username;

    #[SerializedPath('[profile][personal_information][full_name]')]
    private string $fullName;
}

Warning

SerializedPath не можна використовувати у поєднанні з SerializedName для однієї властивості.

Атрибут #[SerializedPath] також застосовується до серіалізації PHP-об'єкта:

1
2
3
4
5
6
use App\Model\Person;
// ...

$person = new Person(123, 'jdoe', 'Jane Doe');
$jsonContent = $serializer->serialize($person, 'json');
// $jsonContent містить {"id":123,"profile":{"username":"jdoe","personal_information":{"full_name":"Jane Doe"}}}

Перетворення імен властивостей при серіалізації та десеріалізації

Іноді серіалізовані атрибути потрібно називати інакше, ніж властивості або методи геттерів/сеттерів PHP-класів. Цього можна за допомогою перетворювачів імен.

Сервіс серіалізатора використовує
MetadataAwareNameConverter. За допомогою цього перетворювача імен ви можете змінити ім'я атрибута, використовуючи атрибут #[SerializedName]:

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

use Symfony\Component\Serializer\Attribute\SerializedName;

class Person
{
    #[SerializedName('customer_name')]
    private string $name;

    // ...
}

Це користувацьке мапування використовується для перетворення імен властивостей під час серіалізації та десеріалізації об'єктів:

1
2
3
4
// ...

$json = $serializer->serialize($person, 'json');
// $json містить {"customer_name":"Jane Doe", ...}

See also

Ви також можете створити користувацький клас перетворювача імен. Детальніше про це можна прочитати у Як створити користувацький перетворювач імен.

CamelCase в snake_case

У багатьох форматах прийнято використовувати нижні підкреслення для розділення слів
(також відомо як як snake_case). Однак у додатках Symfony прийнято використовувати
camelCase для іменування властивостей.

Symfony надає вбудований перетворювач імен, призначений для перетворення між стилями snake_case та CamelCase під час серіалізації та десеріалізації.
Ви можете використовувати його замість перетворювача імен, що враховує метадані,
встановивши налаштування name_converter в значення serializer.name_converter.camel_case_to_snake_case:

1
2
3
4
# config/packages/serializer.yaml
framework:
    serializer:
        name_converter: 'serializer.name_converter.camel_case_to_snake_case'

Нормалізатори Serializer

За замовчуванням сервіс серіалізатора сконфігуровано з такими нормалізаторам
(у порядку пріоритету):

UnwrappingDenormalizer
Можна використовувати для денормалізації лише частини введення, докладніше про
про це далі у цій статті .
ProblemNormalizer
Нормалізує помилки FlattenException
згідно специфікації проблем API RFC 7807.
UidNormalizer

Нормалізує об'єкти, які розширюють AbstractUid.

Формат нормалізації за замовчуванням для об'єктів, що реалізують Uuid - це формат RFC 4122 (приклад: d9e7a184-5d5b-11ea-a62a-3499710062d0). Формат нормалізації за замовчуванням для об'єктів, що реалізують Ulid - це формат Base 32 (приклад: 01E439TP9XJZ9RPFH3T1PYBCR8). Ви можете змінити формат рядка, задавши опцію контексту серіалізатора UidNormalizer::NORMALIZATION_FORMAT_KEY як UidNormalizer::NORMALIZATION_FORMAT_BASE_58, UidNormalizer::NORMALIZATION_FORMAT_BASE_32 або UidNormalizer::NORMALIZATION_FORMAT_RFC_4122.

Також він може денормалізувати рядки uuid або ulid до Uuid` або Ulid. Формат не має значення.

DateTimeNormalizer

Це нормалізує між об'єктами DateTimeInterface (наприклад DateTime і DateTimeImmutable) і рядками, цілими числами або числами з плаваючою комою.

DateTime і DateTimeImmutable) в рядки, цілі числа або числа з плаваючою комою. За замовчуванням, він перетворює їх на рядки,
використовуючи формат RFC 3339. Використайте DateTimeNormalizer::FORMAT_KEY та DateTimeNormalizer::TIMEZONE_KEY для зміни формату.

Для перетворення об'єктів на цілі числа або числа з плаваючою комою, встановіть у серіалізаторі опцію контексту DateTimeNormalizer::CAST_KEY у значення int або float.

7.1

Опція контексту DateTimeNormalizer::CAST_KEY була представлена в Symfony 7.1.

ConstraintViolationListNormalizer
Цей нормалізатор перетворює об'єкти, що реалізують ConstraintViolationListInterface, на список
помилок відповідно до стандарту RFC 7807.
DateTimeZoneNormalizer
Цей нормалізатор перетворює між об'єктами DateTimeZone і рядками, які представляють назву часового поясу згідно зі списком часових поясів PHP.
DateIntervalNormalizer
Це нормалізує між об'єктами та рядками DateInterval. За замовчуванням використовується формат P%yY%mM%dDT%hH%iM%sS. Використовуйте опцію DateIntervalNormalizer::FORMAT_KEY, щоб змінити його.
FormErrorNormalizer

Цей нормалізатор працює з класами, які реалізують FormInterface.

Він отримуватиме помилки з форми та нормалізуватиме їх згідно специфікації
проблем API RFC 7807.

TranslatableNormalizer

Цей нормалізатор перетворює об'єкти, що реалізують TranslatableInterface на перекладений рядок за допомогою translator.

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

BackedEnumNormalizer

Цей нормалізатор перетворює між зчисленням BackedEnum та рядками або цілими числами.

За замовчуванням, якщо дані не є валідним зчисленням, викликається виключення. Якщо ви натомість хочете отримати null, ви можете встановити опцію
BackedEnumNormalizer::ALLOW_INVALID_VALUES.

DataUriNormalizer
Цей нормалізатор перетворює між об'єктами SplFileInfo та рядком даних URI (data:...) таким чином, що файли можуть бути вбудовані в серіалізовані дані.
JsonSerializableNormalizer

Цей нормалізатор працює з класами, які реалізують JsonSerializable.

Він викличе метод JsonSerializable::jsonSerialize() і потім далі нормалізує результат. Це означає, що вкладені класи JsonSerializable також будуть нормалізовані.

Цей нормалізатор особливо корисний, коли ви хочете поступово мігрувати з існуючої кодової бази з використанням простої json_encode на Symfony Serializer, дозволяючи вам змішувати нормалізатори для різних класів.

На відміну від json_encode, можна обробляти циклічні посилання.

ArrayDenormalizer
Цей денормалізатор перетворює масив масивів на масив об'єктів (з заданим типом). Дивіться Робота з масивами .
ObjectNormalizer

Це найпотужніший нормалізатор за замовчуванням, який використовується для будь-яких об'єктів, які не можуть бути нормалізовані іншими нормалізаторами.

Він використовує :doc:`Компонент PropertyAccess </components/property_access>' для читання і запису в об'єкті. Це дозволяє йому отримувати доступ до властивостей безпосередньо або за допомогою геттерів, сеттерів, хассерів, іссерів, каннерів, додавачів та вилучателів. Імена генеруються шляхом видалення get, set, has, is, add або remove з назви методу та перетворення першої літери на малу (наприклад, getFirstName() -> firstName).

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

Danger

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

Вбудовані нормалізатори

Окрім нормалізаторів, зареєстрованих за замовчуванням (див. попередній розділ),
компонент serializer також надає деякі додаткові нормалізатори. Ви можете зареєструвати їх, визначивши сервіс і позначивши його тегом serializer.normalizer . Наприклад, для використання CustomNormalizer вам слід визначити сервіс на кшталт:

1
2
3
4
5
6
7
8
9
# config/services.yaml
services:
    # ...

    # якщо ви використовуєте автоконфігурацію, тег буде застосовано автоматично
    Symfony\Component\Serializer\Normalizer\CustomNormalizer:
        tags:
            # зареєструвати нормалізатор з високим приорітетом (викликається раніше)
            - { name: 'serializer.normalizer', priority: 500 }
CustomNormalizer
Цей нормалізатор викликає метод в об'єкті PHP під час нормалізації.
PHP-об'єкт повинен реалізовувати NormalizableInterface та/або DenormalizableInterface.
GetSetMethodNormalizer

Цей нормалізатор є альтернативою стандартному ObjectNormalizer. Він читає зміст класу, викликаючи "геттери" (публічні
методи, що починаються з get, has, is або can). Він буде денормалізуватиме дані, викликаючи конструктор і "сеттери" (загальнодоступні методи, що починаються з set).

Об'єкти нормалізуються до мапи імен та значень (імена генеруються
шляхом видалення префікса get з імені методу та перетворення

першої літери на малу; наприклад, getFirstName() -> firstName).

PropertyNormalizer

Це ще одна альтернатива ObjectNormalizer. Цей
нормалізатор безпосередньо читає та записує публічні властивості, а також приватні та захищені властивості (як з класу, так і з усіх його батьківських класів), використовуючи PHP-відображення. Він підтримує виклик конструктора під час процесу денормалізації.

Об'єкти нормалізуються у мапу імен властивостей у значення властивостей.

Ви також можете обмежити нормалізатор, щоб він використовував лише властивості з певною видимістю (наприклад, лише публічні властивості) за допомогою опції контексту PropertyNormalizer::NORMALIZE_VISIBILITY. Ви можете встановити будь-яку комбінацію
констант PropertyNormalizer::NORMALIZE_PUBLIC, PropertyNormalizer::NORMALIZE_PROTECTED та PropertyNormalizer::NORMALIZE_PRIVATE:

1
2
3
4
5
6
7
8
9
10
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
// ...

$json = $serializer->serialize($person, 'json', [
    // серіалізувати лише публічні властивості
    PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC,

    // серіалізувати публічні та захищені властивості
    PropertyNormalizer::NORMALIZE_VISIBILITY => PropertyNormalizer::NORMALIZE_PUBLIC | PropertyNormalizer::NORMALIZE_PROTECTED,
]);

Налагодження Serializer

Скористайтеся командою debug:serializer для скидання метаданих серіалізатора для заданого класу:

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
29
30
31
32
$ php bin/console debug:serializer 'App\Entity\Book'

    App\Entity\Book
    ---------------

    +-------------+------------------------------------------------------------+
    | Властивість | Опції                                                      |
    +-------------+------------------------------------------------------------+
    | name        | [                                                          |
    |             |   "groups" => [                                            |
    |             |       "book:read",                                         |
    |             |       "book:write",                                        |
    |             |   ],                                                       |
    |             |   "maxDepth" => 1,                                         |
    |             |   "serializedName" => "book_name",                         |
    |             |   "serializedPath" => null,                                |
    |             |   "ignore" => false,                                       |
    |             |   "normalizationContexts" => [],                           |
    |             |   "denormalizationContexts" => []                          |
    |             | ]                                                          |
    | isbn        | [                                                          |
    |             |   "groups" => [                                            |
    |             |       "book:read",                                         |
    |             |   ],                                                       |
    |             |   "maxDepth" => null,                                      |
    |             |   "serializedName" => null,                                |
    |             |   "serializedPath" => "[data][isbn]",                      |
    |             |   "ignore" => false,                                       |
    |             |   "normalizationContexts" => [],                           |
    |             |   "denormalizationContexts" => []                          |
    |             | ]                                                          |
    +-------------+------------------------------------------------------------+

Просунута серіалізація

Пропуск значень null

За замовчуванням, Serializer зберігатиме властивості, що містять значення null. Ви можете змінити цю поведінку, встановивши опцію контексту AbstractObjectNormalizer::SKIP_NULL_VALUES
у значення true:

1
2
3
4
5
6
7
8
9
10
class Person
{
    public string $name = 'Jane Doe';
    public ?string $gender = null;
}

$jsonContent = $serializer->serialize(new Person(), 'json', [
    AbstractObjectNormalizer::SKIP_NULL_VALUES => true,
]);
// $jsonContent містить {"name":"Jane Doe"}

Робота з неініціалізованими властивостями

У PHP типізовані властивості мають стан uninitialized, який відрізняється від стандартного null нетипізованих властивостей. Коли ви намагаєтеся отримати
доступ до типізованої властивості до того, як надати їй явне значення, ви отримуєте помилку.

Щоб уникнути помилки при серіалізації або нормалізації об'єкта з неініціалізованими
властивостями, за замовчуванням ObjectNormalizer перехоплює ці помилки та ігнорує
такі властивості.

Ви можете вимкнути таку поведінку, встановивши опцію контексту AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES у значення false:

1
2
3
4
5
6
7
8
9
10
class Person {
    public string $name = 'Jane Doe';
    public string $phoneNumber; // uninitialized
}

$jsonContent = $normalizer->serialize(new Dummy(), 'json', [
    AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES => false,
]);
// викликає Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException
// так як ObjectNormalizer не може прочитати неініціалізовані властивості

Note

Використання PropertyNormalizer або :class:Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer з опцією контексту AbstractObjectNormalizer::SKIP_UNINITIALIZED_VALUES, встановленої
як false, викличе екземпляр \Error, якщо заданий об'єкт має неініціалізовані властивості, оскільки нормалізатори не можуть їх прочитати (безпосередньо або через методи геттера/іссера).

Робота з циклічними посиланнями

Циклічні посилання поширені при роботі з асоційованими об'єктами:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Organization
{
    public function __construct(
        private string $name,
        private array $members = []
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function addMember(Member $member): void
    {
        $this->members[] = $member;
    }

    public function getMembers(): array
    {
        return $this->members;
    }
}

class Member
{
    private Organization $organization;

    public function __construct(
        private string $name
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function setOrganization(Organization $organization): void
    {
        $this->organization = $organization;
    }

    public function getOrganization(): Organization
    {
        return $this->organization;
    }
}

Щоб уникнути нескінченних циклів, нормалізатори викликають виключення CircularReferenceException, коли зустрічається такий випадок:

1
2
3
4
5
6
7
8
$organization = new Organization('Les-Tilleuls.coop');
$member = new Member('Kévin');

$organization->addMember($member);
$member->setOrganization($organization);

$jsonContent = $serializer->serialize($organization, 'json');
// викликає CircularReferenceException

Ключ circular_reference_limit у контексті задає кількість разів, яку буде серіалізовано той самий об'єкт, перш ніж вважати його циклічним посиланням. Значення за замовчуванням - 1.

Замість того, щоб викликати виключення, циклічні посилання можна також обробляти з допомогою користувацьких викличних. Це особливо корисно при серіалізації сутностей з унікальними ідентифікаторами :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use Symfony\Component\Serializer\Exception\CircularReferenceException;

$context = [
    AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => function (object $object, ?string $format, array $context): string {
        if (!$object instanceof Organization) {
            throw new CircularReferenceException('A circular reference has been detected when serializing the object of class "'.get_debug_type($object).'".');
        }

        // серіалізувати вкладену Organization тільки з імʼям (а не з членами)
        return $object->getName();
    },
];

$jsonContent = $serializer->serialize($organization, 'json', $context);
// $jsonContent містить {"name":"Les-Tilleuls.coop","members":[{"name":"K\u00e9vin", organization: "Les-Tilleuls.coop"}]}

Робота з глибиною серіалізації

Серіалізатор також може виявляти вкладені об'єкти одного класу і обмежувати глибину серіалізації. Це корисно для деревовидних структур, де один і той самий об'єкт може бути вкладений декілька разів.

Наприклад, припустимо структуру даних родинного дерева:

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
29
// ...
class Person
{
    // ...

    public function __construct(
        private string $name,
        private ?self $mother
    ) {
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getMother(): ?self
    {
        return $this->mother;
    }

    // ...
}

// ...
$greatGrandmother = new Person('Elizabeth', null);
$grandmother = new Person('Jane', $greatGrandmother);
$mother = new Person('Sophie', $grandmother);
$child = new Person('Joe', $mother);

Ви можете вказати максимальну глибину для певної властивості. Наприклад, ви можете встановити максимальну
глибину як 1, щоб завжди серіалізувати лише чиюсь матір (а не бабусю і т.д.):

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

use Symfony\Component\Serializer\Attribute\MaxDepth;

class Person
{
    #[MaxDepth(1)]
    private ?self $mother;

    // ...
}

Щоб обмежити глибину серіалізації, в контексті потрібно встановити ключ AbstractObjectNormalizer::ENABLE_MAX_DEPTH у значення true
(або в контексті за замовчуванням, визначеному у файлі framework.yaml):

1
2
3
4
5
6
7
8
9
10
// ...
$greatGrandmother = new Person('Elizabeth', null);
$grandmother = new Person('Jane', $greatGrandmother);
$mother = new Person('Sophie', $grandmother);
$child = new Person('Joe', $mother);

$jsonContent = $serializer->serialize($child, null, [
    AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true
]);
// $jsonContent містить {"name":"Joe","mother":{"name":"Sophie"}}

Ви також можете сконфігурувати користувацьке викличне, яке буде використано, коли буде досягнуто
максимальної глибини. Це може бути використано, наприклад, для повернення унікального ідентифікатора наступного вкладеного об'єкта, замість того, щоб опускати властивість:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
// ...

$greatGrandmother = new Person('Elizabeth', null);
$grandmother = new Person('Jane', $greatGrandmother);
$mother = new Person('Sophie', $grandmother);
$child = new Person('Joe', $mother);

// всі параметри зворотного виклику є необовʼязковими (ви можете опустити ті, які не використовуєте)
$maxDepthHandler = function (object $innerObject, object $outerObject, string $attributeName, ?string $format = null, array $context = []): ?string {
    // повернути лише імʼя наступної людини в дереві
    return $innerObject instanceof Person ? $innerObject->getName() : null;
};

$jsonContent = $serializer->serialize($child, null, [
    AbstractObjectNormalizer::ENABLE_MAX_DEPTH => true,
    AbstractObjectNormalizer::MAX_DEPTH_HANDLER => $maxDepthHandler,
]);
// $jsonContent містить {"name":"Joe","mother":{"name":"Sophie","mother":"Jane"}}

Використання зворотних викликів для серіалізації властивостей за допомогою екземплярів обʼєктів

Під час серіалізації ви можете задати зворотний виклик для форматування певної властивості

об'єкта. Це можна використовувати замість визначення контексту для групи :

1
2
3
4
5
6
7
8
9
10
11
12
13
$person = new Person('cordoval', 34);
$person->setCreatedAt(new \DateTime('now'));

$context = [
    AbstractNormalizer::CALLBACKS => [
        // всі параметри зворотного виклику є необовʼязковими (ви можете опустити ті, які не використовуєте)
        'createdAt' => function (object $attributeValue, object $object, string $attributeName, ?string $format = null, array $context = []) {
            return $attributeValue instanceof \DateTime ? $attributeValue->format(\DateTime::ATOM) : '';
        },
    ],
];
$jsonContent = $serializer->serialize($person, 'json', $context);
// $jsonContent містить {"name":"cordoval","age":34,"createdAt":"2014-03-22T09:43:12-0500"}

Просунута десеріалізація

Вимагати всі властивості

За замовчуванням, Serializer додасть null до властивостей, які можна обнулити, якщо
для них не вказано параметрів. Ви можете змінити цю поведінку, встановивши опцію контексту AbstractNormalizer::REQUIRE_ALL_PROPERTIES
у значення true:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person
{
    public function __construct(
        public string $firstName,
        public ?string $lastName,
    ) {
    }
}

// ...
$data = ['firstName' => 'John'];
$person = $serializer->deserialize($data, Person::class, 'json', [
    AbstractNormalizer::REQUIRE_ALL_PROPERTIES => true,
]);
// викликає Symfony\Component\Serializer\Exception\MissingConstructorArgumentException

Збір помилок типу під час денормалізації

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

Використовуйте опцію COLLECT_DENORMALIZATION_ERRORS, щоб зібрати всі виключення
одразу, і щоб отримати об'єкт частково денормалізованим:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
try {
    $person = $serializer->deserialize($jsonString, Person::class, 'json', [
        DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true,
    ]);
} catch (PartialDenormalizationException $e) {
    $violations = new ConstraintViolationList();

    /** @var NotNormalizableValueException $exception */
    foreach ($e->getErrors() as $exception) {
        $message = sprintf('The type must be one of "%s" ("%s" given).', implode(', ', $exception->getExpectedTypes()), $exception->getCurrentType());
        $parameters = [];
        if ($exception->canUseMessageForUser()) {
            $parameters['hint'] = $exception->getMessage();
        }
        $violations->add(new ConstraintViolation($message, '', $parameters, null, $exception->getPath(), null));
    }

    // ... повернути список порушень користувачу
}

Десеріалізація в існуючий обʼєкт

Серіалізатор також можна використовувати для оновлення існуючого об'єкта. Ви можете зробити це це за допомогою опції контексту серіалізатора object_to_populate:

1
2
3
4
5
6
7
8
9
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;

// ...
$person = new Person('Jane Doe', 59);

$serializer->deserialize($jsonData, Person::class, 'json', [
    AbstractNormalizer::OBJECT_TO_POPULATE => $person,
]);
// замість повернення нового обʼєкта, натомість оновлюється $person

Note

Опція AbstractNormalizer::OBJECT_TO_POPULATE використовується тільки для об'єкта верхнього рівня. Якщо цей об'єкт є коренем деревовидної структури, всі дочірні елементи, які існують у нормалізованих даних, буде перестворено з новими екземплярами.

Коли опція контексту AbstractObjectNormalizer::DEEP_OBJECT_TO_POPULATE
встановлена у значення true, наявні дочірні об'єкти кореня OBJECT_TO_POPULATE оновлюються з нормалізованих даних, замість того, щоб денормалізатор перестворював їх. Це працює лише для одиночних дочірніх об'єктів, а не для масивів об'єктів. Вони все одно будуть замінені, якщо присутні у нормалізованих даних.

Десеріалізація інтерфейсів та абстрактних класів

При роботі з асоційованими об'єктами властивість іноді посилається на інтерфейс або абстрактний клас. При десеріалізації цих властивостей Serializer повинен знати, який конкретний клас ініціалізувати. Це робиться з допомогою дискримінаторного мапування класів.

Уявіть, що є інтерфейс InvoiceItemInterface, який реалізовано
об'єктами Product та Shipping. При серіалізації об'єкта, серіалізатор додасть додатковий "атрибут дискримінатора". Цей атрибут містить або product, або shipping. Мапа класу дискримінатора зіставляє ці імена типів з реальними іменами класів PHP при десеріалізації:

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

use Symfony\Component\Serializer\Attribute\DiscriminatorMap;

#[DiscriminatorMap(
    typeProperty: 'type',
    mapping: [
        'product' => Product::class,
        'shipping' => Shipping::class,
    ]
)]
interface InvoiceItemInterface
{
    // ...
}

Зі сконфігурованою мапою дискримінатора, серіалізатор тепер може вибрати правильний клас для властивостей, типізованих як InvoiceItemInterface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class InvoiceLine
{
    public function __construct(
        private InvoiceItemInterface $invoiceItem
    ) {
        $this->invoiceItem = $invoiceItem;
    }

    public function getInvoiceItem(): InvoiceItemInterface
    {
        return $this->invoiceItem;
    }

    // ...
}

// ...
$invoiceLine = new InvoiceLine(new Product());

$jsonString = $serializer->serialize($invoiceLine, 'json');
// $jsonString містить {"type":"product",...}

$invoiceLine = $serializer->deserialize($jsonString, InvoiceLine::class, 'json');
// $invoiceLine містить новий InvoiceLine(new Product(...))

Часткова десеріалізація введення (розпаковка)

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

Щоб уникнути десеріалізації всієї відповіді, ви можете використовувати UnwrappingDenormalizer і "розпакувати" дані введення:

1
2
3
4
5
$jsonData = '{"result":"success","data":{"person":{"name": "Jane Doe","age":57}}}';
$data = $serialiser->deserialize($jsonData, Object::class, [
    UnwrappingDenormalizer::UNWRAP_PATH => '[data][person]',
]);
// $data - Person(name: 'Jane Doe', age: 57)

unwrap_path - це шлях властивості компонента PropertyAccess, застосований до денормалізованого масиву.

Робота з аргументами конструктора

Якщо у конструкторі класу визначено аргументи, як це зазвичай буває з Value Objects, серіалізатор зіставлятиме імена параметрів з
десеріалізованими атрибутами. Якщо деяких параметрів не вистачає, буде викликано MissingConstructorArgumentsException.

У цих випадках використовуйте опцію контексту default_constructor_arguments, щоб визначити значення за замовчуванням для відсутніх параметрів:

1
2
3
4
5
6
7
8
9
10
11
use App\Model\Person;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
// ...

$jsonData = '{"age":39,"name":"Jane Doe"}';
$person = $serializer->deserialize($jsonData, Person::class, 'json', [
    AbstractNormalizer::DEFAULT_CONSTRUCTOR_ARGUMENTS => [
        Person::class => ['sportsperson' => true],
    ],
]);
// $person - це Person(name: 'Jane Doe', age: 39, sportsperson: true);

Рекурсивна денормалізація та безпека типів

Якщо доступний ExtractorTypeExtractor, нормалізатор також перевірить, чи дані для денормалізації відповідають типу властивості (навіть для
примітивних типів). Наприклад, якщо надано string, а тип властивості - int, то буде викликано UnexpectedValueException.
Примусове застосування типів для властивостей можна вимкнути за допомогою встановлення опції контексту серіалізатора ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT у значення true.

Робота з булевими занченнями

7.1

Опція контексту AbstractNormalizer::FILTER_BOOL була представлена в Symfony 7.1.

PHP розглядає багато різних значень як істинні або хибні. Наприклад, рядки true,
1 і yes вважаються істинними, тоді як false, 0 і no вважаються хибними.

Під час десеріалізації компонент Serializer може подбати про це автоматично. Це можна зробити за допомогою опції контексту AbstractNormalizer::FILTER_BOOL:

1
2
3
4
5
6
7
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
// ...

$person = $serializer->denormalize(['sportsperson' => 'yes'], Person::class, context: [
    AbstractNormalizer::FILTER_BOOL => true
]);
// $person містить екземпляр Person з sportsperson встановленим як true

Цей контекст змушує процес десеріалізації поводитися як функція filter_var з прапорцем FILTER_VALIDATE_BOOL.

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

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