Skip to content

[WIP] Reorganize the Serializer documentation #6428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The Components
property_access/index
routing/index
security/index
serializer
serializer/index
stopwatch
templating/index
translation/index
Expand Down
8 changes: 5 additions & 3 deletions components/map.rst.inc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
* :doc:`/components/using_components`

* :doc:`/components/browser_kit/index`

* :doc:`/components/browser_kit/introduction`

* :doc:`/components/class_loader/index`
Expand Down Expand Up @@ -121,9 +121,11 @@
* :doc:`/components/security/authorization`
* :doc:`/components/security/secure_tools`

* **Serializer**
* :doc:`/components/serializer/index`

* :doc:`/components/serializer`
* :doc:`/components/serializer/introduction`
* :doc:`/components/serializer/encoders`
* :doc:`/components/serializer/normalizers`

* **Stopwatch**

Expand Down
105 changes: 105 additions & 0 deletions components/serializer/encoders.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
.. index::
single: Serializer, Encoders

Encoders
========

Encoders basically turn **arrays** into **formats** and vice versa.
They implement :class:`Symfony\\Component\\Serializer\\Encoder\\EncoderInterface` for encoding (array to format) and :class:`Symfony\\Component\\Serializer\\Encoder\\DecoderInterface` for decoding (format to array).

You can add new encoders to a Serializer instance by using its second constructor argument::

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Encoder\JsonEncoder;

$encoders = array(new XmlEncoder(), new JsonEncoder());
$serializer = new Serializer(array(), $encoders);

Built-in encoders
-----------------

You can see in the example above that we use two encoders:

* :class:`Symfony\\Component\\Serializer\\Encoder\\XmlEncoder` to encode/decode XML
* :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder` to encode/decode JSON

The ``XmlEncoder``
~~~~~~~~~~~~~~~~~~

This encoder transform arrays into XML and vice versa.

For example, we will guess that you have an object normalized as following::

array('foo' => array(1, 2), 'bar' => true);

The ``XmlEncoder`` will encode this object like that::

<?xml version="1.0"?>
<response>
<foo>1</foo>
<foo>2</foo>
<bar>1</bar>
</response>

Be aware that this encoder will consider keys beginning with ``@`` as attributes::

$encoder = new XmlEncoder();
$encoder->encode(array('foo' => array('@bar' => 'value')));
// will return:
// <?xml version="1.0"?>
// <response>
// <foo bar="value" />
// </response>

The ``JsonEncoder``
~~~~~~~~~~~~~~~~~~~

The ``JsonEncoder`` is much simpler and is based on the PHP `json_encode`_ and `json_decode`_ functions.

.. _json_encode: https://secure.php.net/manual/fr/function.json-encode.php
.. _json_decode: https://secure.php.net/manual/fr/function.json-decode.php

Custom encoders
---------------

If you need to support another format than XML and JSON, you can create your own encoder.
We will guess that you want to serialize and deserialize Yaml. For that, we will use
:doc:`/components/yaml/index`::

namespace App\Encoder;

use Symfony\Component\Serializer\Encoder\DecoderInterface;
use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Yaml\Yaml;

class YamlEncoder implements EncoderInterface, DecoderInterface
{
public function encode($data, $format, array $context = array())
{
return Yaml::dump($data);
}

public function supportsEncoding($format)
{
return 'json' === $format;
}

public function decode($data, $format, array $context = array())
{
return Yaml::parse($data);
}

public function supportsDecoding($format)
{
return 'json' === $format;
}
}

Then just pass it to your serializer::

use Symfony\Component\Serializer\Serializer;

$serializer = new Serializer(array(), array(new App\Encoder\YamlEncoder()));

Now you'll be able to serialize and deserialize Yaml.
9 changes: 9 additions & 0 deletions components/serializer/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Serializer
==========

.. toctree::
:maxdepth: 2

introduction
encoders
normalizers
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,20 @@ which Encoders and Normalizer are going to be available::
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

// Allows to serialize/deserialize in JSON and XML
$encoders = array(new XmlEncoder(), new JsonEncoder());
// Allows to normalize objects thanks to their getters and setters
$normalizers = array(new GetSetMethodNormalizer());

$serializer = new Serializer($normalizers, $encoders);

The following examples assume that you instantiate the serializer as above.

.. note::

Read the dedicated sections to learn more about :doc:`/components/serializer/encoders`
and :doc:`/components/serializer/normalizers`.

Serializing an Object
---------------------

Expand Down Expand Up @@ -105,29 +114,6 @@ The first parameter of the :method:`Symfony\\Component\\Serializer\\Serializer::
is the object to be serialized and the second is used to choose the proper encoder,
in this case :class:`Symfony\\Component\\Serializer\\Encoder\\JsonEncoder`.

Ignoring Attributes when Serializing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.3
The :method:`GetSetMethodNormalizer::setIgnoredAttributes<Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer::setIgnoredAttributes>`
method was introduced in Symfony 2.3.

As an option, there's a way to ignore attributes from the origin object when
serializing. To remove those attributes use the
:method:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer::setIgnoredAttributes`
method on the normalizer definition::

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$normalizer = new GetSetMethodNormalizer();
$normalizer->setIgnoredAttributes(array('age'));
$encoder = new JsonEncoder();

$serializer = new Serializer(array($normalizer), array($encoder));
$serializer->serialize($person, 'json'); // Output: {"name":"foo"}

Deserializing an Object
-----------------------

Expand All @@ -141,6 +127,7 @@ of the ``Person`` class would be encoded in XML format::
</person>
EOF;

// Will return an instance of Acme\Person
$person = $serializer->deserialize($data, 'Acme\Person', 'xml');

In this case, :method:`Symfony\\Component\\Serializer\\Serializer::deserialize`
Expand All @@ -150,69 +137,11 @@ needs three parameters:
#. The name of the class this information will be decoded to
#. The encoder used to convert that information into an array

Using Camelized Method Names for Underscored Attributes
-------------------------------------------------------

.. versionadded:: 2.3
The :method:`GetSetMethodNormalizer::setCamelizedAttributes<Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer::setCamelizedAttributes>`
method was introduced in Symfony 2.3.

Sometimes property names from the serialized content are underscored (e.g.
``first_name``). Normally, these attributes will use get/set methods like
``getFirst_name``, when ``getFirstName`` method is what you really want. To
change that behavior use the
:method:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer::setCamelizedAttributes`
method on the normalizer definition::

$encoder = new JsonEncoder();
$normalizer = new GetSetMethodNormalizer();
$normalizer->setCamelizedAttributes(array('first_name'));

$serializer = new Serializer(array($normalizer), array($encoder));

$json = <<<EOT
{
"name": "foo",
"age": "19",
"first_name": "bar"
}
EOT;

$person = $serializer->deserialize($json, 'Acme\Person', 'json');

As a final result, the deserializer uses the ``first_name`` attribute as if
it were ``firstName`` and uses the ``getFirstName`` and ``setFirstName`` methods.

Using Callbacks to Serialize Properties with Object Instances
-------------------------------------------------------------

When serializing, you can set a callback to format a specific object property::

use Acme\Person;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Serializer;

$encoder = new JsonEncoder();
$normalizer = new GetSetMethodNormalizer();

$callback = function ($dateTime) {
return $dateTime instanceof \DateTime
? $dateTime->format(\DateTime::ISO8601)
: '';
};

$normalizer->setCallbacks(array('createdAt' => $callback));

$serializer = new Serializer(array($normalizer), array($encoder));

$person = new Person();
$person->setName('cordoval');
$person->setAge(34);
$person->setCreatedAt(new \DateTime('now'));
Go further
----------

$serializer->serialize($person, 'json');
// Output: {"name":"cordoval", "age": 34, "createdAt": "2014-03-22T09:43:12-0500"}
If this is not already done, you should take a look at :doc:`/components/serializer/encoders`
and :doc:`/components/serializer/normalizers` to be able to use the entire abilities of this component.

JMSSerializer
-------------
Expand Down
23 changes: 23 additions & 0 deletions components/serializer/normalizers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.. index::
single: Security, Normalizers

Normalizers
===========

Normalizers turn **objects** into **arrays** and vice-versa.
They implement :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface` for normalizing (object to array) and :class:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizerInterface` for denormalizing (array to object).

You can add new normalizers to a Serializer instance by using its first constructor argument::

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;

$normalizers = array(new ArrayDenormalizer(), new GetSetMethodNormalizer());
$serializer = new Serializer($normalizers);

Built-in encoders
-----------------

The Serializer Component provides several normalizers for most use cases:
*
4 changes: 2 additions & 2 deletions cookbook/serializer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ How to Use the Serializer

Serializing and deserializing to and from objects and different formats (e.g.
JSON or XML) is a very complex topic. Symfony comes with a
:doc:`Serializer Component</components/serializer>`, which gives you some
:doc:`Serializer Component</components/serializer/index>`, which gives you some
tools that you can leverage for your solution.

In fact, before you start, get familiar with the serializer, normalizers
and encoders by reading the :doc:`Serializer Component</components/serializer>`.
and encoders by reading the :doc:`Serializer Component</components/serializer/index>`.
You should also check out the `JMSSerializerBundle`_, which expands on the
functionality offered by Symfony's core serializer.

Expand Down
1 change: 1 addition & 0 deletions redirection_map
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
/components/routing /components/routing/introduction
/cookbook/console/generating_urls /cookbook/console/sending_emails
/components/yaml /components/yaml/introduction
/components/serializer /components/serializer/introduction
/components/templating /components/templating/introduction
/cookbook/upgrading /cookbook/upgrade/index
/cookbook/security/voters_data_permission /cookbook/security/voters
Expand Down