Как создать пользовательский преобразователь имен

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

Как создать пользовательский преобразователь имен

Компонент Serializer использует преобразователи имен для преобразования имен атрибутов (например, с snake_case в JSON на CamelCase для свойств PHP).

Представьте, что у вас есть следующий объект:

1
2
3
4
5
6
7
namespace App\Model;

class Company
{
    public string $name;
    public string $address;
}

А в сериализованной форме все атрибуты должны иметь префикс org_, например как здесь:

1
{"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}

Пользовательский преобразователь имен может справиться со следующими случаями:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
namespace App\Serializer;

use Symfony\Component\Serializer\NameConverter\NameConverterInterface;

class OrgPrefixNameConverter implements NameConverterInterface
{
    public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
    {
        // добавить префикс во время нормализации
        return 'org_'.$propertyName;
    }

    public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
    {
        // удалить префикс 'org_' во время денормализации
        return str_starts_with($propertyName, 'org_') ? substr($propertyName, 4) : $propertyName;
    }
}

7.1

Получение доступа к текущему имени класса, формату и контексту через normalize() и denormalize() было представлено в Symfony 7.1.

Note

Вы также можете реализовать AdvancedNameConverterInterface, чтобы получить доступ к текущему имени класса, формату и контексту.

Затем сконфигурируйте сериализатор, чтобы использовать ваш преобразователь имен:

1
2
3
4
5
# config/packages/serializer.yaml
framework:
    serializer:
        # передать ID сервиса вашего преобразователя имен
        name_converter: 'App\Serializer\OrgPrefixNameConverter'

Теперь, при использовании сериализатора в приложении, ко всем атрибутам будет добавлен префикс org_:

1
2
3
4
5
6
7
// ...
$company = new Company('Acme Inc.', '123 Main Street, Big City');

$json = $serializer->serialize($company, 'json');
// {"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
$companyCopy = $serializer->deserialize($json, Company::class, 'json');
// Те же данные, что и $company