Как использовать Serializer
Дата обновления перевода 2023-01-11
Как использовать 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
будет доступен в контейнере.
Он поставляется с набором полезных кодировщиков
и нормализаторов .
Включены кодировщики, поддерживающие следующие форматы:
- JSON: JsonEncoder
- XML: XmlEncoder
- CSV: CsvEncoder
- YAML: YamlEncoder
А также следующие нормализаторы:
- ObjectNormalizer
- DateTimeNormalizer
- DateTimeZoneNormalizer
- DateIntervalNormalizer
- FormErrorNormalizer
- DataUriNormalizer
- JsonSerializableNormalizer
- ArrayDenormalizer
- ConstraintViolationListNormalizer
- ProblemNormalizer
- BackedEnumNormalizer
Другие встроенные нормализаторы и пользовательские нормализаторы и/или кодировщики также могут быть загружены, путем тегирования их как serializer.normalizer и serializer.encoder . Также возможно установить приоритет тега, чтобы опрределить порядок сопоставления.
Caution
Не забывайте загружать DateTimeNormalizer
при сериализации классов
DateTime
или DateTimeImmutable
для избежания излишнего использования
памяти и оголения внутренних деталей.
Контекст сериализатора
Сериализатор может определять контекст для контроля (де)сериализацию источников. Этот контекст передается всем нормализаторам. К примеру:
- DateTimeNormalizer использует
ключ
datetime_format
в формате даты и времени; - AbstractObjectNormalizer
использует
empty_iterable_as_object
, чтобы представлять пустые объекты как{}
вместо[]
в JSON. - Serializer использует
empty_array_as_object
для представления пустых массивов как{}
вместо[]
в 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-систему, поддерживающую следующие форматы:
- JSON-LD вместе со словарем Hydra Core
- OpenAPI v2 (ранее Swagger) и v3
- GraphQL
- JSON:API
- HAL
- JSON
- XML
- YAML
- CSV
Она встроена над фреймворком Symfony и ее компонентом Serializer. Она предоставляет пользовательские нормализаторы и кодировщики, пользовательсские метаданные и систему кеширования.
Если вы хотите воспользоваться преимуществами полной мощи компонента Symfony Serializer, посмотрите на то, как работает этот пакет.