123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- ========
- Overview
- ========
- This bundle allows you to easily serialize/unserialize objects. Main features
- include:
- - able to handle circular references, and object graphs of any depth without
- writing a single line of code
- - serialize/unserialize objects using annotations to describe metadata
- - supports versioning out of the box
- - easily customizable as most logic is implemented using clearly defined
- interfaces
- - can be configured via annotations, YAML, XML, or PHP
- Installation
- ------------
- Checkout a copy of the code::
- git submodule add https://github.com/schmittjoh/SerializerBundle.git src/JMS/SerializerBundle
- Then register the bundle with your kernel::
- // in AppKernel::registerBundles()
- $bundles = array(
- // ...
- new JMS\SerializerBundle\JMSSerializerBundle(),
- // ...
- );
- This bundle also requires the Metadata library::
- git submodule add https://github.com/schmittjoh/metadata.git vendor/metadata
- Make sure that you also register the namespaces with the autoloader::
- // app/autoload.php
- $loader->registerNamespaces(array(
- // ...
- 'JMS' => __DIR__.'/../vendor/bundles',
- 'Metadata' => __DIR__.'/../vendor/metadata/src',
- // ...
- ));
- Note: You need to use the master branch of the metadata library.
- Configuration
- -------------
- Below is the default configuration, you don't need to change it unless it doesn't
- suit your needs::
- jms_serializer:
- handlers:
- datetime:
- format: Y-m-dTH:i:s
- default_timezone: UTC
- array_collection: true
-
- property_naming:
- separator: _
- lower_case: true
-
- metadata:
- cache: file
- debug: %kernel.debug%
- file_cache:
- dir: %kernel.cache_dir%/serializer
-
- # Using auto-detection, the mapping files for each bundle will be
- # expected in the Resources/config/serializer directory.
- #
- # Example:
- # class: My\FooBundle\Entity\User
- # expected path: @MyFooBundle/Resources/config/serializer/Entity.User.(yml|xml|php)
- auto_detection: true
-
- # if you don't want to use auto-detection, you can also define the
- # namespace prefix and the corresponding directory explicitly
- directories:
- any-name:
- namespace_prefix: My\FooBundle
- path: @MyFooBundle/Resources/config/serializer
- another-name:
- namespace_prefix: My\BarBundle
- path: @MyBarBundle/Resources/config/serializer
-
- Usage
- -----
- De-/Serializing Objects
- ~~~~~~~~~~~~~~~~~~~~~~~
- ::
- $serializer = $container->get('serializer');
- $serializer->serialize(new MyObject(), 'json');
- $serializer->serialize(new MyObject(), 'xml');
- The serializer supports JSON, and XML out-of-the-box, and can also handle
- many custom XML features (see below).
- Versioning
- ~~~~~~~~~~
- The bundle allows you to have different versions of your objects. This can be
- achieved by using the @Since, and @Until annotation which both accept a
- standardized PHP version number.
- ::
- <?php
-
- class VersionedObject
- {
- /**
- * @Until("1.0.x")
- */
- private $name;
-
- /**
- * @Since("1.1")
- * @SerializedName("name")
- */
- private $name2;
- }
- If you have annotated your objects like above, you can serializing different
- versions like this::
- <?php
-
- $serializer->setVersion('1.0');
- $serializer->serialize(new VersionObject(), 'json');
- Defining which properties should be serialized
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The default exclusion policy is to exclude nothing, that is all properties of the
- object will be serialized. If you only want to expose a few of the properties,
- then it is easier to change the exclusion policy, and only mark these few properties::
- <?php
- use JMS\SerializerBundle\Annotation\ExclusionPolicy;
- use JMS\SerializerBundle\Annotation\Expose;
- /**
- * The following annotations tells the serializer to skip all properties which
- * have not marked with @Expose.
- *
- * @ExclusionPolicy("all")
- */
- class MyObject
- {
- private $foo;
- private $bar;
- /**
- * @Expose
- */
- private $name;
- }
- Lifecycle Callbacks
- ~~~~~~~~~~~~~~~~~~~
- If you need to run some custom logic during the serialization process, you can use
- one of these lifecycle callbacks: @PerSerialize, @PostSerialize, or @PostDeserialize
- Annotations
- -----------
- @ExclusionPolicy
- ~~~~~~~~~~~~~~~~
- This annotation can be defined on a class to indicate the exclusion strategy
- that should be used for the class.
- +----------+----------------------------------------------------------------+
- | Policy | Description |
- +==========+================================================================+
- | all | all properties are excluded by default; only properties marked |
- | | with @Expose will be serialized/unserialized |
- +----------+----------------------------------------------------------------+
- | none | no properties are excluded by default; all properties except |
- | | those marked with @Exclude will be serialized/unserialized |
- +----------+----------------------------------------------------------------+
- @Exclude
- ~~~~~~~~
- This annotation can be defined on a property to indicate that the property should
- not be serialized/unserialized. Works only in combination with NoneExclusionPolicy.
- @Expose
- ~~~~~~~
- This annotation can be defined on a property to indicate that the property should
- be serialized/unserialized. Works only in combination with AllExclusionPolicy.
- @SerializedName
- ~~~~~~~~~~~~~~~
- This annotation can be defined on a property to define the serialized name for a
- property. If this is not defined, the property will be translated from camel-case
- to a lower-cased underscored name, e.g. camelCase -> camel_case.
- @Since
- ~~~~~~
- This annotation can be defined on a property to specify starting from which
- version this property is available. If an earlier version is serialized, then
- this property is excluded automatically. The version must be in a format that is
- understood by PHP's ``version_compare`` function.
- @Until
- ~~~~~~
- This annotation can be defined on a property to specify until which version this
- property was available. If a later version is serialized, then this property is
- excluded automatically. The version must be in a format that is understood by
- PHP's ``version_compare`` function.
- @PreSerialize
- ~~~~~~~~~~~~~
- This annotation can be defined on a method which is supposed to be called before
- the serialization of the object starts.
- @PostSerialize
- ~~~~~~~~~~~~~~
- This annotation can be defined on a method which is then called directly after the
- object has been serialized.
- @PostDeserialize
- ~~~~~~~~~~~~~~~~
- This annotation can be defined on a method which is supposed to be called after
- the object has been deserialized.
- @Type
- ~~~~~
- This annotation can be defined on a property to specify the type of that property.
- This annotation must only be defined when you want to be able to deserialize an
- object.
- Available Types:
- +---------------------------+--------------------------------------------------+
- | Type | Description |
- +===========================+==================================================+
- | boolean | Primitive boolean |
- +---------------------------+--------------------------------------------------+
- | integer | Primitive integer |
- +---------------------------+--------------------------------------------------+
- | double | Primitive double |
- +---------------------------+--------------------------------------------------+
- | string | Primitive string |
- +---------------------------+--------------------------------------------------+
- | array | An array with arbitrary keys, and values. |
- +---------------------------+--------------------------------------------------+
- | array<T> | A list of type T (T can be any available type). |
- | | Examples: |
- | | array<string>, array<MyNamespace\MyObject>, etc. |
- +---------------------------+--------------------------------------------------+
- | array<K, V> | A map of keys of type K to values of type V. |
- | | Examples: array<string, string>, |
- | | array<string, MyNamespace\MyObject>, etc. |
- +---------------------------+--------------------------------------------------+
- | DateTime | PHP's DateTime object |
- +---------------------------+--------------------------------------------------+
- | T | Where T is a fully qualified class name. |
- +---------------------------+--------------------------------------------------+
- | ArrayCollection<T> | Similar to array<T>, but will be deserialized |
- | | into Doctrine's ArrayCollection class. |
- +---------------------------+--------------------------------------------------+
- | ArrayCollection<K, V> | Similar to array<K, V>, but will be deserialized |
- | | into Doctrine's ArrayCollection class. |
- +---------------------------+--------------------------------------------------+
- Examples::
- <?php
- namespace MyNamespace;
-
- use JMS\SerializerBundle\Annotation\Type;
- class BlogPost
- {
- /**
- * @Type("ArrayCollection<MyNamespace\Comment>")
- */
- private $comments;
- /**
- * @Type("string")
- */
- private $title;
- /**
- * @Type("MyNamespace\Author")
- */
- private $author;
- /**
- * @Type("DateTime")
- */
- private $createdAt;
- /**
- * @Type("boolean")
- */
- private $published;
- /**
- * @Type("array<string, string>")
- */
- private $keyValueStore;
- }
- @XmlRoot
- ~~~~~~~~
- This allows you to specify the name of the top-level element.
- ::
- <?php
-
- use JMS\SerializerBundle\Annotation\XmlRoot;
-
- /** @XmlRoot("user") */
- class User
- {
- private $name = 'Johannes';
- }
-
- Resulting XML::
- <user>
- <name><![CDATA[Johannes]]></name>
- </user>
- @XmlAttribute
- ~~~~~~~~~~~~~
- This allows you to mark properties which should be set as attributes,
- and not as child elements.
- ::
- <?php
-
- use JMS\SerializerBundle\Annotation\XmlAttribute;
-
- class User
- {
- /** @XmlAttribute */
- private $id = 1;
- private $name = 'Johannes';
- }
-
- Resulting XML::
- <result id="1">
- <name><![CDATA[Johannes]]></name>
- </result>
- @XmlList
- ~~~~~~~~
- This allows you to define several properties of how arrays should be
- serialized. This is very similar to @XmlMap, and should be used if the
- keys of the array are not important.
- ::
- <?php
-
- use JMS\SerializerBundle\Annotation\XmlList;
- use JMS\SerializerBundle\Annotation\XmlRoot;
-
- /** @XmlRoot("post") */
- class Post
- {
- /**
- * @XmlList(inline = true, entry = "comment")
- */
- private $comments = array(
- new Comment('Foo'),
- new Comment('Bar'),
- );
- }
-
- class Comment
- {
- private $text;
-
- public function __construct($text)
- {
- $this->text = $text;
- }
- }
- Resulting XML::
- <post>
- <comment>
- <text><![CDATA[Foo]]></text>
- </comment>
- <comment>
- <text><![CDATA[Bar]]></text>
- </comment>
- </post>
- @XmlMap
- ~~~~~~~
- Similar to @XmlList, but the keys of the array are meaningful.
- XML Reference
- -------------
- ::
- <!-- MyBundle\Resources\config\serializer\ClassName.xml -->
- <?xml version="1.0" encoding="UTF-8">
- <serializer>
- <class name="Fully\Qualified\ClassName" exclusion-policy="ALL" xml-root-name="foo-bar" exclude="true">
- <property name="some-property"
- exclude="true"
- expose="true"
- type="string"
- serialized-name="foo"
- since-version="1.0"
- until-version="1.1"
- xml-attribute="true"
- >
- <!-- You can also specify the type as element which is necessary if
- your type contains "<" or ">" characters. -->
- <type><![CDATA[]]></type>
- <xml-list inline="true" entry-name="foobar" />
- <xml-map inline="true" key-attribute-name="foo" entry-name="bar" />
- </property>
- <callback-method name="foo" event="pre-serialize" />
- <callback-method name="bar" event="post-serialize" />
- <callback-method name="baz" event="post-deserialize" />
- </class>
- </serializer>
- YAML Reference
- --------------
- ::
- # MyBundle\Resources\config\serializer\ClassName.xml
- Fully\Qualified\ClassName:
- exclusion_policy: ALL
- xml_root_name: foobar
- exclude: true
- properties:
- some-property:
- exclude: true
- expose: true
- type: string
- serialized_name: foo
- since_version: 1.0
- until_version: 1.1
- xml_attribute: true
- xml_list:
- inline: true
- entry_name: foo
- xml_map:
- inline: true
- key_attribute_name: foo
- entry_name: bar
- callback_methods:
- pre_serialize: [foo, bar]
- post_serialize: [foo, bar]
- post_deserialize: [foo, bar]
|