Як використовувати Serializer
Дата оновлення перекладу 2024-06-10
Як використовувати 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 14
// src/Controller/DefaultController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Serializer\SerializerInterface;
class DefaultController extends AbstractController
{
public function index(SerializerInterface $serializer): Response
{
// продовжуйте читати для прикладу використання
}
}
Або ви можете використати фільтр Twig serialize
у шаблоні:
1
{{ object|serialize(format = 'json') }}
Див. довідник twig, щоб дізнатися більше інформації.
Додавання нормалізаторів та кодувальників
Після підключення, сервіс serializer
буде доступний у контейнері. Він постачається
з набором корисних кодувальників та
нормалізаторів .
Включені кодувальники, які підтримують наступні формати:
- JSON: JsonEncoder
- XML: XmlEncoder
- CSV: CsvEncoder
- YAML: YamlEncoder
А також наступні нормалізатори:
- ObjectNormalizer
- DateTimeNormalizer
- DateTimeZoneNormalizer
- DateIntervalNormalizer
- FormErrorNormalizer
- DataUriNormalizer
- JsonSerializableNormalizer
- ArrayDenormalizer
- ConstraintViolationListNormalizer
- ProblemNormalizer
- BackedEnumNormalizer
- TranslatableNormalizer
Інші вбудовані нормалізатори та користувацькі нормалізатори та/або кодувальники також можна завантажити, тегувавши їх як serializer.normalizer та serializer.encoder . Також можливо встановити пріоритет тегу для того, щоб вирішити порядок співствалення.
Danger
Не забувайте завантажувати 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',
]);
Ви також можете сконфігурувати контекст за замовчуванням через конфігурацію фреймворку:
1 2 3 4 5 6 7
# config/packages/framework.yaml
framework:
# ...
serializer:
default_context:
enable_max_depth: true
yaml_indentation: 2
Ви також можете вказати контекст для кожної властивості окремо:
1 2 3 4 5 6 7 8 9 10 11 12
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 \DateTimeInterface $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 => '!Y-m-d'], // To prevent to have the time from the moment of denormalization
)]
public \DateTimeInterface $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 \DateTimeInterface $createdAt;
// ...
}
Атрибут може повторюватися в одній властивості стільки разів, скільки потрібно. Контекст без групи завжди застосовується першим. Потім контекст для груп, що співпали, зливається у наданому порядку.
Якщо ви повторюєте один і той самий контекст у декількох властивостях, розгляньте можливість використання атрибуту
#[Контекст]
у вашому класі, щоб застосувати цю конфігурацію контексту до
до всіх властивостей класу:
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;
#[Context([DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339])]
#[Context(
context: [DateTimeNormalizer::FORMAT_KEY => \DateTime::RFC3339_EXTENDED],
groups: ['extended'],
)]
class Person
{
// ...
}
Використання будівників контексту
Щоб визначити контекст (де)серіалізації, ви можете викоритати "будівники контексту", які є обʼєктами, що допомагають вам створювати цей контекст, надаючи автозаповнення, валідацію та документацію:
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 int $id;
#[ORM\Column(type: 'string', length: 255)]
#[Groups(['show_product', 'list_product'])]
private string $name;
#[ORM\Column(type: 'text')]
#[Groups(['show_product'])]
private string $description;
}
Ви також можете використовувати атрибут #[Groups]
на рівні класу:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#[ORM\Entity]
#[Groups(['show_product'])]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(['list_product'])]
private int $id;
#[ORM\Column(type: 'string', length: 255)]
#[Groups(['list_product'])]
private string $name;
#[ORM\Column(type: 'text')]
private string $description;
}
У цьому прикладі властивості id
і name
належать до груп
show_product
та list_product
. Властивість description
належить лише до групи show_product
.
Тепер, коли ваші групи визначено, ви можете вибрати, які групи використовувати при серіалізації:
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/
.
Note
Групи, що використовуються за замовчуванням при нормалізації та денормалізації об'єктів є
Default
і тією групою, яка відповідає назві класу. Наприклад, якщо ви
нормалізуєте об'єкт App\Entity\Product
, то будуть використані групи
Default
та Product
.
7.1
Використання за замовчуванням імені класу та груп Default
при нормалізації
та денормалізації об'єктів було представлено у Symfony 7.1.
Використання вкладених атрибутів
Щоб мапувати вкладені властивості, використайте конфігурацію SerializedPath
, щоб
визначити їх шляхи, використовуючи валідний синтаксис PropertyAccess:
1 2 3 4 5 6 7 8 9 10 11
namespace App\Model;
use Symfony\Component\Serializer\Annotation\SerializedPath;
class Person
{
#[SerializedPath('[profile][information][birthday]')]
private string $birthday;
// ...
}
Використовуючи конфігурацію вище, денормалізація з нормалізатором, обізнаним про
метадані, запише поле 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
:
1 2 3 4 5
# config/packages/framework.yaml
framework:
# ...
serializer:
name_converter: 'serializer.name_converter.camel_case_to_snake_case'
Налагодження 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" => [] |
| | ] |
+-------------+------------------------------------------------------------+
Поглиблене використання Serializer
Платформа API надає API-систему, яка підтримує наступні формати:
- JSON-LD разом із словником Hydra Core
- OpenAPI v2 (раніше Swagger) і v3
- GraphQL
- JSON:API
- HAL
- JSON
- XML
- YAML
- CSV
Вона вбудована над фреймворком Symfony та її компонентом Serializer. Вона надає користувацькі нормалізатори та кодувальники, користувацькі метадані та систему кешування.
Якщо ви хочете скористатися перевагами повної потужності компонента Symfony Serializer, подвіться на те, як працює цей пакет.