Skip to content

Commit b59b752

Browse files
committed
[Serializer] Name Converter
1 parent 921f3cd commit b59b752

File tree

1 file changed

+102
-23
lines changed

1 file changed

+102
-23
lines changed

components/serializer.rst

Lines changed: 102 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -162,38 +162,117 @@ needs three parameters:
162162
2. The name of the class this information will be decoded to
163163
3. 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 PHP class'
173+
properties or getter and setter methods.
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+
namespace Acme;
181+
182+
class Company
183+
{
184+
public name;
185+
public address;
186+
}
187+
188+
189+
And in the serialized form, all attributes must be prefixed by ``org_`` like
190+
the following::
191+
192+
{"org_name": "Les-Tilleuls.coop", "org_address": "Euratechnologies, 2 rue Hegel, 59160 Lomme, France"}
193+
194+
A custom Name Converter can handle such cases::
195+
196+
namespace MySerializer;
197+
198+
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
199+
200+
class OrgPrefixNameConverter implements NameConverterInterface
201+
{
202+
public function normalize($propertyName)
203+
{
204+
return 'org_'.$propertyName;
205+
}
206+
207+
public function denormalize($propertyName)
208+
{
209+
return substr($propertyName, 4)
210+
}
211+
}
212+
213+
The custom normalizer can be used by passing it as second parameter of any
214+
class extending :class:`Symfony\\Component\\Serializer\\Normalizer\\AbstractNormalizer`,
215+
including :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`
216+
and :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer`::
217+
218+
use Acme\Company;
219+
use Symfony\Component\Serializer\Encoder\JsonEncoder
220+
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
221+
use Symfony\Component\Serializer\Serializer;
222+
use MySerializer\OrgPrefixNameConverter;
223+
224+
$nameConverter = new OrgPrefixNameConverter();
225+
$normalizer = new PropertyNormalizer(null, $nameConverter);
226+
227+
$serializer = new Serializer(array(new JsonEncoder()), array($normalizer));
228+
229+
$obj = new Company();
230+
$obj->name = 'Les-Tilleuls.coop';
231+
$obj->address = 'Euratechnologies, 2 rue Hegel, 59160 Lomme, France';
232+
233+
$json = $serializer->serialize($obj);
234+
$objCopy = $serializer->deserialize($json);
235+
236+
CamelCase to Underscore
237+
~~~~~~~~~~~~~~~~~~~~~~~
238+
239+
.. versionadded:: 2.7
240+
The :class:`Symfony\\Component\\Serializer\\NameConverter\\CamelCaseToUnderscoreNameConverter`
241+
interface was introduced in Symfony 2.7.
242+
243+
It's common in many formats to use underscores to separate words. However,
244+
PSR-2 specify that the preferred style for PHP properties and methods is
245+
CamelCase.
184246

185-
$json = <<<EOT
247+
Symfony provides a built-in Name Converter designed to translate between
248+
underscored and CamelCased styles during serialization and deserialization
249+
processes::
250+
251+
use Symfony\Component\Serializer\NameConverter\CamelCaseToUnderscoreNameConverter;
252+
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
253+
254+
$normalizer = new GetSetMethodNormalizer(null, new CamelCaseToUnderscoreNameConverter());
255+
256+
class Person
186257
{
187-
"name": "foo",
188-
"age": "19",
189-
"first_name": "bar"
258+
private $givenName;
259+
260+
public function __construct($givenName)
261+
{
262+
$this->givenName = $givenName;
263+
}
264+
265+
public function getGivenName()
266+
{
267+
return $this->givenName;
268+
}
190269
}
191-
EOT;
192270

193-
$person = $serializer->deserialize($json, 'Acme\Person', 'json');
271+
$kevin = new Person('Kévin');
272+
$normalizer->normalize($kevin);
273+
// ['given_name' => 'Kévin'];
194274

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.
275+
$anne = $normalizer->denormalize(array('given_name' => 'Anne'), 'Person');
197276

198277
Serializing Boolean Attributes
199278
------------------------------

0 commit comments

Comments
 (0)