Кодувальники Serializer

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

Кодувальники Serializer

Компонент Serializer надає декілька вбудованих кодувальників:

JsonEncoder
Цей клас шифрує та розшифровує дані у форматі JSON.
XmlEncoder
Цей клас шифрує та розшифровує дані у форматі XML.
YamlEncoder
Цей кодувальник шифрує та розшифровує дані у форматі YAML. Цей кодувальник вимагає
компонент Yaml.
CsvEncoder
Цей кодувальник шифрує та розшифровує дані у форматі CSV.

Note

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

Всі ці кодувальники увімкнено за замовчуванням при використанні компонента Serializer у додатку Symfony.

JsonEncoder

JsonEncoder зашифровує да розшифровує JSON-рядки, спираючись на PHP-функції json_encode і json_decode.

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

1
2
3
$this->serializer->serialize($data, 'json', [
    'json_encode_options' => \JSON_PRESERVE_ZERO_FRACTION,
]);

Ось всі опції контексту, доступні для кодувальника JSON :

json_decode_associative (за замовчуванням: false)
Якщо встановлено як true - повертає результат у вигляді масиву, в іншому випадку - повертає вкладену ієрархію stdClass.
json_decode_detailed_errors (за замовчуванням: false)
Якщо встановлено як true - виключення, що викликаються при аналізі JSON, більш конкретні. Вимагає пакет seld/jsonlint.
json_decode_options (за замовчуванням: 0)
Прапорці, передані функції json_decode.
json_encode_options (за замовчуванням: \JSON_PRESERVE_ZERO_FRACTION)
Прапорці, передані функції json_encode.
json_decode_recursion_depth (за замовчуванням: 512)
Встановлює максимальну глибину рекурсії.

CsvEncoder

CsvEncoder зашифровує та розшифровує CSV. Доступні декілька
опцій контексту для налаштування поведінки кодувальника:

csv_delimiter (за замовчуванням: ,)
Встановлює роздільник полів, що розділяє значення (лише один символ).
csv_enclosure (за замовчуванням: ")
Встановлює замикання поля (тільки один символ).
csv_end_of_line (за замовчуванням: \n)
Встановлює символ(и) для позначення кінця кожного рядка у файлі CSV.

csv_escape_char (за замовчуванням: порожній рядок)

7.2

Опція csv_escape_char застаріла, починаючи з Symfony 7.2.

Встановлює символ екранування (максимум один символ).

csv_key_separator (за замовчуванням: .)
Встановлює роздільник для ключів масиву під час його вирівнювання
csv_headers (за замовчуванням: [], виведено з ключів даних введення)
Встановлює порядок заголовка та стовпців даних. Наприклад, якщо ви встановите значення ['a', 'b', 'c'] і серіалізуєте ['c' => 3, 'a' => 1, 'b' => 2], порядок буде a,b,c замість порядку введення (c,a,b).
csv_escape_formulas (за замовчуванням: false)
Екранує поля, що містять формули, додаючи до них символ \t на початку.
as_collection (за замовчуванням: true)
Завжди повертає результати у вигляді колекції, навіть якщо розшифровано лише один рядок.
no_headers (за замовчуванням: false)
Якщо встановлено false, то при денормалізації буде використано перший рядок як заголовки, якщо true - генерує числові заголовки.

output_utf8_bom (за замовчуванням: false) Виводить спеціальний UTF-8 BOM разом із зашифрованими даними.

XmlEncoder

Цей кодувальник перетворює PHP-значення на XML і навпаки.

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

1
$normalizedArray = ['foo' => [1, 2], 'bar' => true];

XmlEncoder зашифрує цей обʼєкт так:

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8" ?>
<response>
    <foo>1</foo>
    <foo>2</foo>
    <bar>1</bar>
</response>

Спеціальний ключ # можна використати для визначення даних вузла:

1
2
3
4
5
6
7
8
9
10
['foo' => ['@bar' => 'value', '#' => 'baz']];

/* зашифровано наступним чином:
   <?xml version="1.0"?>
   <response>
       <foo bar="value">
          baz
       </foo>
   </response>
 */

Крім того, ключі, що починаються з @, вважатимуться атрибутами, а ключ #comment можна використовувати для шифрування XML-коментарів:

1
2
3
4
5
6
7
8
9
10
11
12
$encoder = new XmlEncoder();
$xml = $encoder->encode([
    'foo' => ['@bar' => 'value'],
    'qux' => ['#comment' => 'A comment'],
], 'xml');
/* поверне:
   <?xml version="1.0"?>
   <response>
       <foo bar="value"/>
       <qux><!-- A comment --!><qux>
   </response>
 */

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

Можливо, вам доведеться додати деякі атрибути до кореневого вузла:

1
2
3
4
5
6
7
8
9
10
11
12
$encoder = new XmlEncoder();
$encoder->encode([
    '@attribute1' => 'foo',
    '@attribute2' => 'bar',
    '#' => ['foo' => ['@bar' => 'value', '#' => 'baz']]
], 'xml');

// поверне:
// <?xml version="1.0"?>
// <response attribute1="foo" attribute2="bar">
// <foo bar="value">baz</foo>
// </response>

Tip

За замовчуванням XML-коментарі ігноруються при розшифровуванні змісту, але цю поведінку
можна змінити за допомогою необов'язкового ключа контексту XmlEncoder::DECODER_IGNORED_NODE_TYPES.

Дані з ключами #comment за замовчуванням зашифровуються у XML-коментарі. Це можна змінити,
додавши опцію \XML_COMMENT_NODE до ключа XmlEncoder::ENCODER_IGNORED_NODE_TYPES $defaultContext конструктора XmlEncoder або безпосередньо до аргументу $context
методу encode():

1
$xmlEncoder->encode($array, 'xml', [XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [\XML_COMMENT_NODE]]);

Опції контексту XmlEncoder

Ці опції доступні у контексті серіалізатора :

xml_format_output (за замовчуванням: false)
Якщо встановлено як true - форматує згенерований XML з розривами рядків та відступами.
xml_version (за замовчуванням: 1.0)
Встановлює атрибут версії XML.
xml_encoding (за замовчуванням: utf-8)
Встановлює атрибут шифрування XML.
xml_standalone (за замовчуванням: true)
Додає окремий атрибут до згенерованого XML.
xml_type_cast_attributes (за замовчуванням: true)
Це надає можливість забути про приведення типів атрибутів.
xml_root_node_name (за замовчуванням: response)
Встановлює ім'я кореневого вузла.
as_collection (за замовчуванням: false)
Завжди повертає результати у вигляді колекції, навіть якщо розшифровано лише один рядок.
decoder_ignored_node_types (за замовчуванням: [\XML_PI_NODE, \XML_COMMENT_NODE])
Масив типів вузлів (константи DOM XML_*) для ігнорування при розшифровуванні.
encoder_ignored_node_types (за замовчуванням: [])
Масив типів вузлів (константи DOM XML_*) для ігнорування при шифруванні.
load_options (за замовчуванням: \LIBXML_NONET | \LIBXML_NOBLANKS)
XML, що завантажує опції з libxml.
save_options (за замовчуванням: 0)
XML, що зберігає опції з libxml.
remove_empty_tags (за замовчуванням: false)
Якщо встановлено як true - видаляє всі порожні теги у згенерованому XML.
cdata_wrapping (за замовчуванням: true)
Якщо встановлено як false - не буде обгортати будь-яке значення, що містить один з наступних символів ( <, >, &) у розділ CDATA, наприклад так: <![CDATA[...]]>.
cdata_wrapping_pattern (за замовчуванням: ``/[<>&]/``)
Патерн регулярного виразу для визначення того, чи потрібно обгортати значення у розділ CDATA.

7.1

Опція cdata_wrapping_pattern була представлена в Symfony 7.1.

Приклад з користувацьким context:

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
use Symfony\Component\Serializer\Encoder\XmlEncoder;

$data = [
    'id' => 'IDHNQIItNyQ',
    'date' => '2019-10-24',
];

$xmlEncoder->encode($data, 'xml', ['xml_format_output' => true]);
// виводить:
// <?xml version="1.0"?>
// <response>
//   <id>IDHNQIItNyQ</id>
//   <date>2019-10-24</date>
// </response>

$xmlEncoder->encode($data, 'xml', [
    'xml_format_output' => true,
    'xml_root_node_name' => 'track',
    'encoder_ignored_node_types' => [
        \XML_PI_NODE, // видаляє оголошення XML (перший xml-тег)
    ],
]);
// виводить:
// <track>
//   <id>IDHNQIItNyQ</id>
//   <date>2019-10-24</date>
// </track>

YamlEncoder

Цей кодувальник потребує Компонент Yaml та перетворює з та на Yaml.

Як і для інших кодувальників, для нього доступні декілька
опцій контексту :

yaml_inline (за замовчуванням: 0)
Рівень, на якому ви переходите на вбудований YAML.
yaml_indent (за замовчуванням: 0)
Рівень відступу (використовується внутрішньо).
yaml_flags (за замовчуванням: 0)
Бітове поле констант Yaml::DUMP_*/Yaml::PARSE_* для налаштування шифрування/розшифровування YAML-рядка.

Створення користувацького кодувальника

Уявіть, що ви хочете серіалізувати та десеріалізувати NEON. Для цього вам потрібно створити власний кодувальник:

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

use Nette\Neon\Neon;
use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;

class NeonEncoder implements EncoderInterface, DecoderInterface
{
    public function encode($data, string $format, array $context = [])
    {
        return Neon::encode($data);
    }

    public function supportsEncoding(string $format)
    {
        return 'neon' === $format;
    }

    public function decode(string $data, string $format, array $context = [])
    {
        return Neon::decode($data);
    }

    public function supportsDecoding(string $format)
    {
        return 'neon' === $format;
    }
}

Tip

Якщо вам потрібен доступ до $context у вашому методі supportsDecoding або supportsEncoding, переконайтеся, що реалізовано Symfony\Component\Serializer\Encoder\ContextAwareDecoderInterface'' або SymfonyComponentSerializerEncoderContextAwareEncoderInterface``, відповідно.

Реєстрація у вашому додатку

Якщо ви використовуєте Symfony Framework, то, ймовірно, ви захочете зареєструвати цей кодувальник як сервіс у вашому додатку. Якщо ви використовуєте
конфігурацію services.yaml за замовчуванням , це буде зроблено автоматично!

Якщо ви не використовуєте автоконфігурацію , переконайтеся, що зареєстрували свій клас як сервіс і позначили його тегом serializer.encoder :

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

    App\Serializer\NeonEncoder:
        tags: ['serializer.encoder']

Тепер ви зможете серіалізувати та десеріалізувати NEON!