index.rst 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. ========
  2. Overview
  3. ========
  4. This bundle allows you to easily serialize/unserialize objects. Main features
  5. include:
  6. - able to handle circular references, and object graphs of any depth without
  7. writing a single line of code
  8. - serialize/unserialize objects using annotations to describe metadata
  9. - supports versioning out of the box
  10. - easily customizable as most logic is implemented using clearly defined
  11. interfaces
  12. - can be configured via annotations, YAML, XML, or PHP
  13. Installation
  14. ------------
  15. Checkout a copy of the code::
  16. git submodule add https://github.com/schmittjoh/SerializerBundle.git src/JMS/SerializerBundle
  17. Then register the bundle with your kernel::
  18. // in AppKernel::registerBundles()
  19. $bundles = array(
  20. // ...
  21. new JMS\SerializerBundle\JMSSerializerBundle(),
  22. // ...
  23. );
  24. This bundle also requires the Metadata library::
  25. git submodule add https://github.com/schmittjoh/metadata.git vendor/metadata
  26. Make sure that you also register the namespaces with the autoloader::
  27. // app/autoload.php
  28. $loader->registerNamespaces(array(
  29. // ...
  30. 'JMS' => __DIR__.'/../vendor/bundles',
  31. 'Metadata' => __DIR__.'/../vendor/metadata/src',
  32. // ...
  33. ));
  34. Note: You need to use the master branch of the metadata library.
  35. Configuration
  36. -------------
  37. Below is the default configuration, you don't need to change it unless it doesn't
  38. suit your needs::
  39. jms_serializer:
  40. handlers:
  41. datetime:
  42. format: Y-m-dTH:i:s
  43. default_timezone: UTC
  44. array_collection: true
  45. property_naming:
  46. separator: _
  47. lower_case: true
  48. metadata:
  49. cache: file
  50. debug: %kernel.debug%
  51. file_cache:
  52. dir: %kernel.cache_dir%/serializer
  53. # Using auto-detection, the mapping files for each bundle will be
  54. # expected in the Resources/config/serializer directory.
  55. #
  56. # Example:
  57. # class: My\FooBundle\Entity\User
  58. # expected path: @MyFooBundle/Resources/config/serializer/Entity.User.(yml|xml|php)
  59. auto_detection: true
  60. # if you don't want to use auto-detection, you can also define the
  61. # namespace prefix and the corresponding directory explicitly
  62. directories:
  63. any-name:
  64. namespace_prefix: My\FooBundle
  65. path: @MyFooBundle/Resources/config/serializer
  66. another-name:
  67. namespace_prefix: My\BarBundle
  68. path: @MyBarBundle/Resources/config/serializer
  69. Usage
  70. -----
  71. De-/Serializing Objects
  72. ~~~~~~~~~~~~~~~~~~~~~~~
  73. ::
  74. $serializer = $container->get('serializer');
  75. $serializer->serialize(new MyObject(), 'json');
  76. $serializer->serialize(new MyObject(), 'xml');
  77. The serializer supports JSON, and XML out-of-the-box, and can also handle
  78. many custom XML features (see below).
  79. Versioning
  80. ~~~~~~~~~~
  81. The bundle allows you to have different versions of your objects. This can be
  82. achieved by using the @Since, and @Until annotation which both accept a
  83. standardized PHP version number.
  84. ::
  85. <?php
  86. class VersionedObject
  87. {
  88. /**
  89. * @Until("1.0.x")
  90. */
  91. private $name;
  92. /**
  93. * @Since("1.1")
  94. * @SerializedName("name")
  95. */
  96. private $name2;
  97. }
  98. If you have annotated your objects like above, you can serializing different
  99. versions like this::
  100. <?php
  101. $serializer->setVersion('1.0');
  102. $serializer->serialize(new VersionObject(), 'json');
  103. Defining which properties should be serialized
  104. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105. The default exclusion policy is to exclude nothing, that is all properties of the
  106. object will be serialized. If you only want to expose a few of the properties,
  107. then it is easier to change the exclusion policy, and only mark these few properties::
  108. <?php
  109. use JMS\SerializerBundle\Annotation\ExclusionPolicy;
  110. use JMS\SerializerBundle\Annotation\Expose;
  111. /**
  112. * The following annotations tells the serializer to skip all properties which
  113. * have not marked with @Expose.
  114. *
  115. * @ExclusionPolicy("all")
  116. */
  117. class MyObject
  118. {
  119. private $foo;
  120. private $bar;
  121. /**
  122. * @Expose
  123. */
  124. private $name;
  125. }
  126. Lifecycle Callbacks
  127. ~~~~~~~~~~~~~~~~~~~
  128. If you need to run some custom logic during the serialization process, you can use
  129. one of these lifecycle callbacks: @PerSerialize, @PostSerialize, or @PostDeserialize
  130. Annotations
  131. -----------
  132. @ExclusionPolicy
  133. ~~~~~~~~~~~~~~~~
  134. This annotation can be defined on a class to indicate the exclusion strategy
  135. that should be used for the class.
  136. +----------+----------------------------------------------------------------+
  137. | Policy | Description |
  138. +==========+================================================================+
  139. | all | all properties are excluded by default; only properties marked |
  140. | | with @Expose will be serialized/unserialized |
  141. +----------+----------------------------------------------------------------+
  142. | none | no properties are excluded by default; all properties except |
  143. | | those marked with @Exclude will be serialized/unserialized |
  144. +----------+----------------------------------------------------------------+
  145. @Exclude
  146. ~~~~~~~~
  147. This annotation can be defined on a property to indicate that the property should
  148. not be serialized/unserialized. Works only in combination with NoneExclusionPolicy.
  149. @Expose
  150. ~~~~~~~
  151. This annotation can be defined on a property to indicate that the property should
  152. be serialized/unserialized. Works only in combination with AllExclusionPolicy.
  153. @SerializedName
  154. ~~~~~~~~~~~~~~~
  155. This annotation can be defined on a property to define the serialized name for a
  156. property. If this is not defined, the property will be translated from camel-case
  157. to a lower-cased underscored name, e.g. camelCase -> camel_case.
  158. @Since
  159. ~~~~~~
  160. This annotation can be defined on a property to specify starting from which
  161. version this property is available. If an earlier version is serialized, then
  162. this property is excluded automatically. The version must be in a format that is
  163. understood by PHP's ``version_compare`` function.
  164. @Until
  165. ~~~~~~
  166. This annotation can be defined on a property to specify until which version this
  167. property was available. If a later version is serialized, then this property is
  168. excluded automatically. The version must be in a format that is understood by
  169. PHP's ``version_compare`` function.
  170. @PreSerialize
  171. ~~~~~~~~~~~~~
  172. This annotation can be defined on a method which is supposed to be called before
  173. the serialization of the object starts.
  174. @PostSerialize
  175. ~~~~~~~~~~~~~~
  176. This annotation can be defined on a method which is then called directly after the
  177. object has been serialized.
  178. @PostDeserialize
  179. ~~~~~~~~~~~~~~~~
  180. This annotation can be defined on a method which is supposed to be called after
  181. the object has been deserialized.
  182. @Type
  183. ~~~~~
  184. This annotation can be defined on a property to specify the type of that property.
  185. This annotation must only be defined when you want to be able to deserialize an
  186. object.
  187. Available Types:
  188. +---------------------------+--------------------------------------------------+
  189. | Type | Description |
  190. +===========================+==================================================+
  191. | boolean | Primitive boolean |
  192. +---------------------------+--------------------------------------------------+
  193. | integer | Primitive integer |
  194. +---------------------------+--------------------------------------------------+
  195. | double | Primitive double |
  196. +---------------------------+--------------------------------------------------+
  197. | string | Primitive string |
  198. +---------------------------+--------------------------------------------------+
  199. | array | An array with arbitrary keys, and values. |
  200. +---------------------------+--------------------------------------------------+
  201. | array<T> | A list of type T (T can be any available type). |
  202. | | Examples: |
  203. | | array<string>, array<MyNamespace\MyObject>, etc. |
  204. +---------------------------+--------------------------------------------------+
  205. | array<K, V> | A map of keys of type K to values of type V. |
  206. | | Examples: array<string, string>, |
  207. | | array<string, MyNamespace\MyObject>, etc. |
  208. +---------------------------+--------------------------------------------------+
  209. | DateTime | PHP's DateTime object |
  210. +---------------------------+--------------------------------------------------+
  211. | T | Where T is a fully qualified class name. |
  212. +---------------------------+--------------------------------------------------+
  213. | ArrayCollection<T> | Similar to array<T>, but will be deserialized |
  214. | | into Doctrine's ArrayCollection class. |
  215. +---------------------------+--------------------------------------------------+
  216. | ArrayCollection<K, V> | Similar to array<K, V>, but will be deserialized |
  217. | | into Doctrine's ArrayCollection class. |
  218. +---------------------------+--------------------------------------------------+
  219. Examples::
  220. <?php
  221. namespace MyNamespace;
  222. use JMS\SerializerBundle\Annotation\Type;
  223. class BlogPost
  224. {
  225. /**
  226. * @Type("ArrayCollection<MyNamespace\Comment>")
  227. */
  228. private $comments;
  229. /**
  230. * @Type("string")
  231. */
  232. private $title;
  233. /**
  234. * @Type("MyNamespace\Author")
  235. */
  236. private $author;
  237. /**
  238. * @Type("DateTime")
  239. */
  240. private $createdAt;
  241. /**
  242. * @Type("boolean")
  243. */
  244. private $published;
  245. /**
  246. * @Type("array<string, string>")
  247. */
  248. private $keyValueStore;
  249. }
  250. @XmlRoot
  251. ~~~~~~~~
  252. This allows you to specify the name of the top-level element.
  253. ::
  254. <?php
  255. use JMS\SerializerBundle\Annotation\XmlRoot;
  256. /** @XmlRoot("user") */
  257. class User
  258. {
  259. private $name = 'Johannes';
  260. }
  261. Resulting XML::
  262. <user>
  263. <name><![CDATA[Johannes]]></name>
  264. </user>
  265. @XmlAttribute
  266. ~~~~~~~~~~~~~
  267. This allows you to mark properties which should be set as attributes,
  268. and not as child elements.
  269. ::
  270. <?php
  271. use JMS\SerializerBundle\Annotation\XmlAttribute;
  272. class User
  273. {
  274. /** @XmlAttribute */
  275. private $id = 1;
  276. private $name = 'Johannes';
  277. }
  278. Resulting XML::
  279. <result id="1">
  280. <name><![CDATA[Johannes]]></name>
  281. </result>
  282. @XmlList
  283. ~~~~~~~~
  284. This allows you to define several properties of how arrays should be
  285. serialized. This is very similar to @XmlMap, and should be used if the
  286. keys of the array are not important.
  287. ::
  288. <?php
  289. use JMS\SerializerBundle\Annotation\XmlList;
  290. use JMS\SerializerBundle\Annotation\XmlRoot;
  291. /** @XmlRoot("post") */
  292. class Post
  293. {
  294. /**
  295. * @XmlList(inline = true, entry = "comment")
  296. */
  297. private $comments = array(
  298. new Comment('Foo'),
  299. new Comment('Bar'),
  300. );
  301. }
  302. class Comment
  303. {
  304. private $text;
  305. public function __construct($text)
  306. {
  307. $this->text = $text;
  308. }
  309. }
  310. Resulting XML::
  311. <post>
  312. <comment>
  313. <text><![CDATA[Foo]]></text>
  314. </comment>
  315. <comment>
  316. <text><![CDATA[Bar]]></text>
  317. </comment>
  318. </post>
  319. @XmlMap
  320. ~~~~~~~
  321. Similar to @XmlList, but the keys of the array are meaningful.
  322. XML Reference
  323. -------------
  324. ::
  325. <!-- MyBundle\Resources\config\serializer\ClassName.xml -->
  326. <?xml version="1.0" encoding="UTF-8">
  327. <serializer>
  328. <class name="Fully\Qualified\ClassName" exclusion-policy="ALL" xml-root-name="foo-bar" exclude="true">
  329. <property name="some-property"
  330. exclude="true"
  331. expose="true"
  332. type="string"
  333. serialized-name="foo"
  334. since-version="1.0"
  335. until-version="1.1"
  336. xml-attribute="true"
  337. >
  338. <!-- You can also specify the type as element which is necessary if
  339. your type contains "<" or ">" characters. -->
  340. <type><![CDATA[]]></type>
  341. <xml-list inline="true" entry-name="foobar" />
  342. <xml-map inline="true" key-attribute-name="foo" entry-name="bar" />
  343. </property>
  344. <callback-method name="foo" event="pre-serialize" />
  345. <callback-method name="bar" event="post-serialize" />
  346. <callback-method name="baz" event="post-deserialize" />
  347. </class>
  348. </serializer>
  349. YAML Reference
  350. --------------
  351. ::
  352. # MyBundle\Resources\config\serializer\ClassName.xml
  353. Fully\Qualified\ClassName:
  354. exclusion_policy: ALL
  355. xml_root_name: foobar
  356. exclude: true
  357. properties:
  358. some-property:
  359. exclude: true
  360. expose: true
  361. type: string
  362. serialized_name: foo
  363. since_version: 1.0
  364. until_version: 1.1
  365. xml_attribute: true
  366. xml_list:
  367. inline: true
  368. entry_name: foo
  369. xml_map:
  370. inline: true
  371. key_attribute_name: foo
  372. entry_name: bar
  373. callback_methods:
  374. pre_serialize: [foo, bar]
  375. post_serialize: [foo, bar]
  376. post_deserialize: [foo, bar]