Files
archived-symfony-docs/serializer/custom_name_converter.rst
2024-12-17 09:36:38 +01:00

113 lines
3.8 KiB
ReStructuredText

How to Create your Custom Name Converter
========================================
The Serializer Component uses :ref:`name converters <serializer-name-conversion>`
to transform the attribute names (e.g. from snake_case in JSON to CamelCase
for PHP properties).
Imagine you have the following object::
namespace App\Model;
class Company
{
public string $name;
public string $address;
}
And in the serialized form, all attributes must be prefixed by ``org_`` like
the following:
.. code-block:: json
{"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
A custom name converter can handle such cases::
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
{
// during normalization, add the prefix
return 'org_'.$propertyName;
}
public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
{
// remove the 'org_' prefix on denormalizing
return str_starts_with($propertyName, 'org_') ? substr($propertyName, 4) : $propertyName;
}
}
.. versionadded:: 7.1
Accessing the current class name, format and context via
:method:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::normalize`
and :method:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface::denormalize`
was introduced in Symfony 7.1.
.. note::
You can also implement
:class:`Symfony\\Component\\Serializer\\NameConverter\\AdvancedNameConverterInterface`
to access the current class name, format and context.
Then, configure the serializer to use your name converter:
.. configuration-block::
.. code-block:: yaml
# config/packages/serializer.yaml
framework:
serializer:
# pass the service ID of your name converter
name_converter: 'App\Serializer\OrgPrefixNameConverter'
.. code-block:: xml
<!-- config/packages/serializer.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<!-- pass the service ID of your name converter -->
<framework:serializer
name-converter="App\Serializer\OrgPrefixNameConverter"
/>
</framework:config>
</container>
.. code-block:: php
// config/packages/serializer.php
use App\Serializer\OrgPrefixNameConverter;
use Symfony\Config\FrameworkConfig;
return static function (FrameworkConfig $framework) {
$framework->serializer()
// pass the service ID of your name converter
->nameConverter(OrgPrefixNameConverter::class)
;
};
Now, when using the serializer in the application, all attributes will be
prefixed by ``org_``::
// ...
$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');
// Same data as $company