Skip to content

Commit f8e2e19

Browse files
committed
feature #4692 [Serializer] Name Converter (dunglas)
This PR was merged into the 2.7 branch. Discussion ---------- [Serializer] Name Converter | Q | A | --------------- | --- | Doc fix? | no | New docs? | yes symfony/symfony#13120 | Applies to | 2.7 This is the documentation for the Serializer Name Converter feature. Commits ------- d335005 [Serializer] Fix CS 0442752 [Serializer] Acme things 57e6c94 [Serializer] Name Converter fixes 24d0320 [Serializer] Use firtName and snake_case 4ecc706 [Serializer] Name Converter corrections. b59b752 [Serializer] Name Converter
2 parents d3192a7 + d335005 commit f8e2e19

File tree

1 file changed

+101
-23
lines changed

1 file changed

+101
-23
lines changed

components/serializer.rst

Lines changed: 101 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -162,38 +162,116 @@ needs three parameters:
162162
#. The name of the class this information will be decoded to
163163
#. The encoder used to convert that information into an array
164164

165-
Using Camelized Method Names for Underscored Attributes
166-
-------------------------------------------------------
165+
Converting Property Names when Serializing and Deserializing
166+
------------------------------------------------------------
167167

168-
.. versionadded:: 2.3
169-
The :method:`GetSetMethodNormalizer::setCamelizedAttributes<Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer::setCamelizedAttributes>`
170-
method was introduced in Symfony 2.3.
168+
.. versionadded:: 2.7
169+
The :class:`Symfony\\Component\\Serializer\\NameConverter\\NameConverterInterface`
170+
interface was introduced in Symfony 2.7.
171171

172-
Sometimes property names from the serialized content are underscored (e.g.
173-
``first_name``). Normally, these attributes will use get/set methods like
174-
``getFirst_name``, when ``getFirstName`` method is what you really want. To
175-
change that behavior use the
176-
:method:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer::setCamelizedAttributes`
177-
method on the normalizer definition::
172+
Sometimes serialized attributes must be named differently than properties
173+
or getter/setter methods of PHP classes.
178174

179-
$encoder = new JsonEncoder();
180-
$normalizer = new GetSetMethodNormalizer();
181-
$normalizer->setCamelizedAttributes(array('first_name'));
175+
The Serializer Component provides a handy way to translate or map PHP field
176+
names to serialized names: The Name Converter System.
182177

183-
$serializer = new Serializer(array($normalizer), array($encoder));
178+
Given you have the following object::
179+
180+
class Company
181+
{
182+
public name;
183+
public address;
184+
}
185+
186+
And in the serialized form, all attributes must be prefixed by ``org_`` like
187+
the following::
188+
189+
{"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
184190

185-
$json = <<<EOT
191+
A custom name converter can handle such cases::
192+
193+
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
194+
195+
class OrgPrefixNameConverter implements NameConverterInterface
186196
{
187-
"name": "foo",
188-
"age": "19",
189-
"first_name": "bar"
197+
public function normalize($propertyName)
198+
{
199+
return 'org_'.$propertyName;
200+
}
201+
202+
public function denormalize($propertyName)
203+
{
204+
// remove org_ prefix
205+
return 'org_' === substr($propertyName, 0, 4) ? substr($propertyName, 4) : $propertyName;
206+
}
207+
}
208+
209+
The custom normalizer can be used by passing it as second parameter of any
210+
class extending :class:`Symfony\\Component\\Serializer\\Normalizer\\AbstractNormalizer`,
211+
including :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
212+
and :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`::
213+
214+
use Symfony\Component\Serializer\Encoder\JsonEncoder
215+
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
216+
use Symfony\Component\Serializer\Serializer;
217+
218+
$nameConverter = new OrgPrefixNameConverter();
219+
$normalizer = new PropertyNormalizer(null, $nameConverter);
220+
221+
$serializer = new Serializer(array(new JsonEncoder()), array($normalizer));
222+
223+
$obj = new Company();
224+
$obj->name = 'Acme Inc.';
225+
$obj->address = '123 Main Street, Big City';
226+
227+
$json = $serializer->serialize($obj);
228+
// {"org_name": "Acme Inc.", "org_address": "123 Main Street, Big City"}
229+
$objCopy = $serializer->deserialize($json);
230+
// Same data as $obj
231+
232+
.. _using-camelized-method-names-for-underscored-attributes:
233+
234+
CamelCase to snake_case
235+
~~~~~~~~~~~~~~~~~~~~~~~
236+
237+
.. versionadded:: 2.7
238+
The :class:`Symfony\\Component\\Serializer\\NameConverter\\CamelCaseToUnderscoreNameConverter`
239+
interface was introduced in Symfony 2.7.
240+
241+
In many formats, it's common to use underscores to separate words (also known
242+
as snake_case). However, PSR-1 specifies that the preferred style for PHP
243+
properties and methods is CamelCase.
244+
245+
Symfony provides a built-in name converter designed to transform between
246+
snake_case and CamelCased styles during serialization and deserialization
247+
processes::
248+
249+
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
250+
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
251+
252+
$normalizer = new GetSetMethodNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
253+
254+
class Person
255+
{
256+
private $firstName;
257+
258+
public function __construct($firstName)
259+
{
260+
$this->firstName = $firstName;
261+
}
262+
263+
public function getFirstName()
264+
{
265+
return $this->firstName;
266+
}
190267
}
191-
EOT;
192268

193-
$person = $serializer->deserialize($json, 'Acme\Person', 'json');
269+
$kevin = new Person('Kévin');
270+
$normalizer->normalize($kevin);
271+
// ['first_name' => 'Kévin'];
194272

195-
As a final result, the deserializer uses the ``first_name`` attribute as if
196-
it were ``firstName`` and uses the ``getFirstName`` and ``setFirstName`` methods.
273+
$anne = $normalizer->denormalize(array('first_name' => 'Anne'), 'Person');
274+
// Person object with firstName: 'Anne'
197275

198276
Serializing Boolean Attributes
199277
------------------------------

0 commit comments

Comments
 (0)