Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Serializer] Add documentation about the (de)serialization of interfaces and abstract classes #9016

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

Merged
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
81 changes: 81 additions & 0 deletions 81 components/serializer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,87 @@ will be thrown. The type enforcement of the properties can be disabled by settin
the serializer context option ``ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT``
to ``true``.

Serializing Interfaces and Abstract Classes
-------------------------------------------

When dealing with objects that are fairly similar or share properties, you may
use interfaces or abstract classes. The Serializer component allows you to
serialize and deserialize these objects using a *"discrimator class mapping"*.

The discriminator is the field (in the serialized string) used to differentiate
between the possible objects. In practice, when using the Serializer component,
pass the :class:`Symfony\\Component\\Serializer\\Mapping\\ClassDiscriminatorResolver`
to the :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer`.

Consider an application that defines an abstract ``CodeRepository`` class
extended by ``GitHubCodeRepository`` and ``BitBucketCodeRepository`` classes.
This example shows how to serialize and deserialize those objects::

$discriminator = new ClassDiscriminatorResolver();
$discriminator->addClassMapping(CodeRepository::class, new ClassDiscriminatorMapping('type', [
'github' => GitHubCodeRepository::class,
'bitbucket' => BitBucketCodeRepository::class,
]));

$serializer = new Serializer(
array(new ObjectNormalizer(null, null, null, null, $discriminator)),
array('json' => new JsonEncoder())
);

$serialized = $serializer->serialize(new GitHubCodeRepository());
// {"type": "github"}

$repository = $serializer->unserialize($serialized, CodeRepository::class, 'json');
// instanceof GitHubCodeRepository

If the class metadata factory is enabled as explained in the
:ref:`Attributes Groups section <component-serializer-attributes-groups>`, you
can use this simpler configuration:

.. configuration-block::

.. code-block:: php-annotations

namespace App;

use Symfony\Component\Serializer\Annotation\DiscriminatorMap;

/**
* @DiscriminatorMap(typeProperty="type", mapping={
* "github"="App\GitHubCodeRepository",
* "bitbucket"="App\BitBucketCodeRepository"
* })
*/
interface CodeRepository
{
// ...
}

.. code-block:: yaml

App\CodeRepository:
discriminator_map:
type_property: type
mapping:
github: 'App\GitHubCodeRepository'
bitbucket: 'App\BitBucketCodeRepository'

.. code-block:: xml

<?xml version="1.0" ?>
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping
http://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
>
<class name="App\CodeRepository">
<discriminator-map type-property="type">
<mapping type="github" class="App\GitHubCodeRepository" />
<mapping type="bitbucket" class="App\BitBucketCodeRepository" />
</discriminator-map>
</class>
</serializer>

Learn more
----------

Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.