@@ -981,6 +981,87 @@ will be thrown. The type enforcement of the properties can be disabled by settin
981
981
the serializer context option ``ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT ``
982
982
to ``true ``.
983
983
984
+ Serializing Interfaces and Abstract Classes
985
+ -------------------------------------------
986
+
987
+ When dealing with objects that are fairly similar or share properties, you may
988
+ use interfaces or abstract classes. The Serializer component allows you to
989
+ serialize and deserialize these objects using a *"discrimator class mapping" *.
990
+
991
+ The discriminator is the field (in the serialized string) used to differentiate
992
+ between the possible objects. In practice, when using the Serializer component,
993
+ pass the :class: `Symfony\\ Component\\ Serializer\\ Mapping\\ ClassDiscriminatorResolver `
994
+ to the :class: `Symfony\\ Component\\ Serializer\\ Normalizer\\ ObjectNormalizer `.
995
+
996
+ Consider an application that defines an abstract ``CodeRepository `` class
997
+ extended by ``GitHubCodeRepository `` and ``BitBucketCodeRepository `` classes.
998
+ This example shows how to serialize and deserialize those objects::
999
+
1000
+ $discriminator = new ClassDiscriminatorResolver();
1001
+ $discriminator->addClassMapping(CodeRepository::class, new ClassDiscriminatorMapping('type', [
1002
+ 'github' => GitHubCodeRepository::class,
1003
+ 'bitbucket' => BitBucketCodeRepository::class,
1004
+ ]));
1005
+
1006
+ $serializer = new Serializer(
1007
+ array(new ObjectNormalizer(null, null, null, null, $discriminator)),
1008
+ array('json' => new JsonEncoder())
1009
+ );
1010
+
1011
+ $serialized = $serializer->serialize(new GitHubCodeRepository());
1012
+ // {"type": "github"}
1013
+
1014
+ $repository = $serializer->unserialize($serialized, CodeRepository::class, 'json');
1015
+ // instanceof GitHubCodeRepository
1016
+
1017
+ If the class metadata factory is enabled as explained in the
1018
+ :ref: `Attributes Groups section <component-serializer-attributes-groups >`, you
1019
+ can use this simpler configuration:
1020
+
1021
+ .. configuration-block ::
1022
+
1023
+ .. code-block :: php-annotations
1024
+
1025
+ namespace App;
1026
+
1027
+ use Symfony\Component\Serializer\Annotation\DiscriminatorMap;
1028
+
1029
+ /**
1030
+ * @DiscriminatorMap(typeProperty="type", mapping={
1031
+ * "github"="App\GitHubCodeRepository",
1032
+ * "bitbucket"="App\BitBucketCodeRepository"
1033
+ * })
1034
+ */
1035
+ interface CodeRepository
1036
+ {
1037
+ // ...
1038
+ }
1039
+
1040
+ .. code-block :: yaml
1041
+
1042
+ App\CodeRepository :
1043
+ discriminator_map :
1044
+ type_property : type
1045
+ mapping :
1046
+ github : ' App\GitHubCodeRepository'
1047
+ bitbucket : ' App\BitBucketCodeRepository'
1048
+
1049
+ .. code-block :: xml
1050
+
1051
+ <?xml version =" 1.0" ?>
1052
+ <serializer xmlns =" http://symfony.com/schema/dic/serializer-mapping"
1053
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1054
+ xsi : schemaLocation =" http://symfony.com/schema/dic/serializer-mapping
1055
+ http://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
1056
+ >
1057
+ <class name =" App\CodeRepository" >
1058
+ <discriminator-map type-property =" type" >
1059
+ <mapping type =" github" class =" App\GitHubCodeRepository" />
1060
+ <mapping type =" bitbucket" class =" App\BitBucketCodeRepository" />
1061
+ </discriminator-map >
1062
+ </class >
1063
+ </serializer >
1064
+
984
1065
Learn more
985
1066
----------
986
1067
0 commit comments