diff --git a/components/serializer.rst b/components/serializer.rst index 9584b10f450..b3bfed16e14 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -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 `, 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 + + + + + + + + + + + Learn more ----------