Кодировщики Serializer

Дата обновления перевода 2025-02-15

Кодировщики 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 или Symfony\Component\Serializer\Encoder\ContextAwareEncoderInterface, соответственно.

Регистрация в вашем приложении

Если вы используете Symfony Framework, то вы, вероятно, захотите зарегистрировать этот кодировщик в качестве сервиса в вашем приложении. Если вы используете
конфигурацию services.yaml по умолчанию , это будет сделано автоматически!

Если вы не используете автоконфигурацию , убедитесь, что зарегистрировали свой класс как сервис и пометили его тегом serializer.encoder :

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

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

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