annotations.rst 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. Annotations
  2. -----------
  3. @ExclusionPolicy
  4. ~~~~~~~~~~~~~~~~
  5. This annotation can be defined on a class to indicate the exclusion strategy
  6. that should be used for the class.
  7. +----------+----------------------------------------------------------------+
  8. | Policy | Description |
  9. +==========+================================================================+
  10. | all | all properties are excluded by default; only properties marked |
  11. | | with @Expose will be serialized/unserialized |
  12. +----------+----------------------------------------------------------------+
  13. | none | no properties are excluded by default; all properties except |
  14. | | those marked with @Exclude will be serialized/unserialized |
  15. +----------+----------------------------------------------------------------+
  16. @Exclude
  17. ~~~~~~~~
  18. This annotation can be defined on a property to indicate that the property should
  19. not be serialized/unserialized. Works only in combination with NoneExclusionPolicy.
  20. If the ``ExpressionLanguageExclusionStrategy`` exclusion strategy is enabled, will
  21. be possible to use ``@Exclude(if="expression")`` to exclude dynamically a property.
  22. @Expose
  23. ~~~~~~~
  24. This annotation can be defined on a property to indicate that the property should
  25. be serialized/unserialized. Works only in combination with AllExclusionPolicy.
  26. If the ``ExpressionLanguageExclusionStrategy`` exclusion strategy is enabled, will
  27. be possible to use ``@Expose(if="expression")`` to expose dynamically a property.
  28. @SkipWhenEmpty
  29. ~~~~~~~~~~~~~~
  30. This annotation can be defined on a property to indicate that the property should
  31. not be serialized if the result will be "empty".
  32. Works option works only when serializing.
  33. @SerializedName
  34. ~~~~~~~~~~~~~~~
  35. This annotation can be defined on a property to define the serialized name for a
  36. property. If this is not defined, the property will be translated from camel-case
  37. to a lower-cased underscored name, e.g. camelCase -> camel_case.
  38. Note that this annotation is not used when you're using any other naming
  39. stategy than the default configuration (which includes the
  40. ``SerializedNameAnnotationStrategy``). In order to re-enable the annotation, you
  41. will need to wrap your custom strategy with the ``SerializedNameAnnotationStrategy``.
  42. .. code-block :: php
  43. <?php
  44. $serializer = \JMS\Serializer\SerializerBuilder::create()
  45. ->setPropertyNamingStrategy(
  46. new \JMS\Serializer\Naming\SerializedNameAnnotationStrategy(
  47. new \JMS\Serializer\Naming\IdenticalPropertyNamingStrategy()
  48. )
  49. )
  50. ->build();
  51. @Since
  52. ~~~~~~
  53. This annotation can be defined on a property to specify starting from which
  54. version this property is available. If an earlier version is serialized, then
  55. this property is excluded automatically. The version must be in a format that is
  56. understood by PHP's ``version_compare`` function.
  57. @Until
  58. ~~~~~~
  59. This annotation can be defined on a property to specify until which version this
  60. property was available. If a later version is serialized, then this property is
  61. excluded automatically. The version must be in a format that is understood by
  62. PHP's ``version_compare`` function.
  63. @Groups
  64. ~~~~~~~
  65. This annotation can be defined on a property to specify if the property
  66. should be serialized when only serializing specific groups (see
  67. :doc:`../cookbook/exclusion_strategies`).
  68. @MaxDepth
  69. ~~~~~~~~~
  70. This annotation can be defined on a property to limit the depth to which the
  71. content will be serialized. It is very useful when a property will contain a
  72. large object graph.
  73. @AccessType
  74. ~~~~~~~~~~~
  75. This annotation can be defined on a property, or a class to specify in which way
  76. the properties should be accessed. By default, the serializer will retrieve, or
  77. set the value via reflection, but you may change this to use a public method instead:
  78. .. code-block :: php
  79. <?php
  80. use JMS\Serializer\Annotation\AccessType;
  81. /** @AccessType("public_method") */
  82. class User
  83. {
  84. private $name;
  85. public function getName()
  86. {
  87. return $this->name;
  88. }
  89. public function setName($name)
  90. {
  91. $this->name = trim($name);
  92. }
  93. }
  94. @Accessor
  95. ~~~~~~~~~
  96. This annotation can be defined on a property to specify which public method should
  97. be called to retrieve, or set the value of the given property:
  98. .. code-block :: php
  99. <?php
  100. use JMS\Serializer\Annotation\Accessor;
  101. class User
  102. {
  103. private $id;
  104. /** @Accessor(getter="getTrimmedName",setter="setName") */
  105. private $name;
  106. // ...
  107. public function getTrimmedName()
  108. {
  109. return trim($this->name);
  110. }
  111. public function setName($name)
  112. {
  113. $this->name = $name;
  114. }
  115. }
  116. .. note ::
  117. If you need only to serialize your data, you can avoid providing a setter by
  118. setting the property as read-only using the ``@ReadOnly`` annotation.
  119. @AccessorOrder
  120. ~~~~~~~~~~~~~~
  121. This annotation can be defined on a class to control the order of properties. By
  122. default the order is undefined, but you may change it to either "alphabetical", or
  123. "custom".
  124. .. code-block :: php
  125. <?php
  126. use JMS\Serializer\Annotation\AccessorOrder;
  127. /**
  128. * @AccessorOrder("alphabetical")
  129. *
  130. * Resulting Property Order: id, name
  131. */
  132. class User
  133. {
  134. private $id;
  135. private $name;
  136. }
  137. /**
  138. * @AccessorOrder("custom", custom = {"name", "id"})
  139. *
  140. * Resulting Property Order: name, id
  141. */
  142. class User
  143. {
  144. private $id;
  145. private $name;
  146. }
  147. /**
  148. * @AccessorOrder("custom", custom = {"name", "someMethod" ,"id"})
  149. *
  150. * Resulting Property Order: name, mood, id
  151. */
  152. class User
  153. {
  154. private $id;
  155. private $name;
  156. /**
  157. * @Serializer\VirtualProperty
  158. * @Serializer\SerializedName("mood")
  159. *
  160. * @return string
  161. */
  162. public function getSomeMethod()
  163. {
  164. return 'happy';
  165. }
  166. }
  167. @VirtualProperty
  168. ~~~~~~~~~~~~~~~~
  169. This annotation can be defined on a method to indicate that the data returned by
  170. the method should appear like a property of the object.
  171. A virtual property can be defined for a method of an object to serialize and can be
  172. also defined at class level exposing data using the Symfony Expression Language.
  173. .. code-block :: php
  174. /**
  175. * @Serializer\VirtualProperty(
  176. * "firstName",
  177. * exp="object.getFirstName()",
  178. * options={@Serializer\SerializedName("my_first_name")}
  179. * )
  180. */
  181. class Author
  182. {
  183. /**
  184. * @Serializer\Expose()
  185. */
  186. private $id;
  187. /**
  188. * @Serializer\Exclude()
  189. */
  190. private $firstName;
  191. /**
  192. * @Serializer\Exclude()
  193. */
  194. private $lastName;
  195. /**
  196. * @Serializer\VirtualProperty()
  197. */
  198. public function getLastName()
  199. {
  200. return $this->lastName;
  201. }
  202. public function getFirstName()
  203. {
  204. return $this->firstName;
  205. }
  206. }
  207. In this example:
  208. - ``id`` is exposed using the object reflection.
  209. - ``lastName`` is exposed using the ``getLastName`` getter method.
  210. - ``firstName`` is exposed using the ``object.getFirstName()`` expression (``exp`` can contain any valid symfony expression).
  211. .. note ::
  212. This only works for serialization and is completely ignored during deserialization.
  213. @Inline
  214. ~~~~~~~
  215. This annotation can be defined on a property to indicate that the data of the property
  216. should be inlined.
  217. **Note**: This only works for serialization, the serializer will not be able to deserialize
  218. objects with this annotation. Also, AccessorOrder will be using the name of the property
  219. to determine the order.
  220. @ReadOnly
  221. ~~~~~~~~~
  222. This annotation can be defined on a property to indicate that the data of the property
  223. is read only and cannot be set during deserialization.
  224. A property can be marked as non read only with ``@ReadOnly(false)`` annotation (useful when a class is marked as read only).
  225. @PreSerialize
  226. ~~~~~~~~~~~~~
  227. This annotation can be defined on a method which is supposed to be called before
  228. the serialization of the object starts.
  229. @PostSerialize
  230. ~~~~~~~~~~~~~~
  231. This annotation can be defined on a method which is then called directly after the
  232. object has been serialized.
  233. @PostDeserialize
  234. ~~~~~~~~~~~~~~~~
  235. This annotation can be defined on a method which is supposed to be called after
  236. the object has been deserialized.
  237. @HandlerCallback
  238. ~~~~~~~~~~~~~~~~
  239. This annotation can be defined on a method if serialization/deserialization is handled
  240. by the object itself.
  241. .. code-block :: php
  242. <?php
  243. class Article
  244. {
  245. /**
  246. * @HandlerCallback("xml", direction = "serialization")
  247. */
  248. public function serializeToXml(XmlSerializationVisitor $visitor)
  249. {
  250. // custom logic here
  251. }
  252. }
  253. @Discriminator
  254. ~~~~~~~~~~~~~~
  255. .. versionadded : 0.12
  256. @Discriminator was added
  257. This annotation allows serialization/deserialization of relations which are polymorphic, but
  258. where a common base class exists. The ``@Discriminator`` annotation has to be applied
  259. to the least super type::
  260. /**
  261. * @Discriminator(field = "type", disabled = false, map = {"car": "Car", "moped": "Moped"}, groups={"foo", "bar"})
  262. */
  263. abstract class Vehicle { }
  264. class Car extends Vehicle { }
  265. class Moped extends Vehicle { }
  266. .. note ::
  267. `groups` is optional and is used as exclusion policy.
  268. @Type
  269. ~~~~~
  270. This annotation can be defined on a property to specify the type of that property.
  271. For deserialization, this annotation must be defined.
  272. The ``@Type`` annotation can have parameters and parameters can be used by serialization/deserialization
  273. handlers to enhance the serialization or deserialization result; for example, you may want to
  274. force a certain format to be used for serializing DateTime types and specifying at the same time a different format
  275. used when deserializing them.
  276. Available Types:
  277. +----------------------------------------------------------+--------------------------------------------------+
  278. | Type | Description |
  279. +==========================================================+==================================================+
  280. | boolean or bool | Primitive boolean |
  281. +----------------------------------------------------------+--------------------------------------------------+
  282. | integer or int | Primitive integer |
  283. +----------------------------------------------------------+--------------------------------------------------+
  284. | double or float | Primitive double |
  285. +----------------------------------------------------------+--------------------------------------------------+
  286. | string | Primitive string |
  287. +----------------------------------------------------------+--------------------------------------------------+
  288. | array | An array with arbitrary keys, and values. |
  289. +----------------------------------------------------------+--------------------------------------------------+
  290. | array<T> | A list of type T (T can be any available type). |
  291. | | Examples: |
  292. | | array<string>, array<MyNamespace\MyObject>, etc. |
  293. +----------------------------------------------------------+--------------------------------------------------+
  294. | array<K, V> | A map of keys of type K to values of type V. |
  295. | | Examples: array<string, string>, |
  296. | | array<string, MyNamespace\MyObject>, etc. |
  297. +----------------------------------------------------------+--------------------------------------------------+
  298. | DateTime | PHP's DateTime object (default format*/timezone) |
  299. +----------------------------------------------------------+--------------------------------------------------+
  300. | DateTime<'format'> | PHP's DateTime object (custom format/default |
  301. | | timezone) |
  302. +----------------------------------------------------------+--------------------------------------------------+
  303. | DateTime<'format', 'zone'> | PHP's DateTime object (custom format/timezone) |
  304. +----------------------------------------------------------+--------------------------------------------------+
  305. | DateTime<'format', 'zone', 'deserializeFormat'> | PHP's DateTime object (custom format/timezone, |
  306. | | deserialize format). If you do not want to |
  307. | | specify a specific timezone, use an empty |
  308. | | string (''). |
  309. +----------------------------------------------------------+--------------------------------------------------+
  310. | DateTimeImmutable | PHP's DateTimeImmutable object (default format*/ |
  311. | | timezone) |
  312. +----------------------------------------------------------+--------------------------------------------------+
  313. | DateTimeImmutable<'format'> | PHP's DateTimeImmutable object (custom format/ |
  314. | | default timezone) |
  315. +----------------------------------------------------------+--------------------------------------------------+
  316. | DateTimeImmutable<'format', 'zone'> | PHP's DateTimeImmutable object (custom format/ |
  317. | | timezone) |
  318. +----------------------------------------------------------+--------------------------------------------------+
  319. | DateTimeImmutable<'format', 'zone', 'deserializeFormat'> | PHP's DateTimeImmutable object (custom format/ |
  320. | | timezone/deserialize format). If you do not want |
  321. | | to specify a specific timezone, use an empty |
  322. | | string (''). |
  323. +----------------------------------------------------------+--------------------------------------------------+
  324. | DateInterval | PHP's DateInterval object using ISO 8601 format |
  325. +----------------------------------------------------------+--------------------------------------------------+
  326. | T | Where T is a fully qualified class name. |
  327. +----------------------------------------------------------+--------------------------------------------------+
  328. | ArrayCollection<T> | Similar to array<T>, but will be deserialized |
  329. | | into Doctrine's ArrayCollection class. |
  330. +----------------------------------------------------------+--------------------------------------------------+
  331. | ArrayCollection<K, V> | Similar to array<K, V>, but will be deserialized |
  332. | | into Doctrine's ArrayCollection class. |
  333. +----------------------------------------------------------+--------------------------------------------------+
  334. (*) If the standalone jms/serializer is used then default format is `\DateTime::ISO8601` (which is not compatible with ISO-8601 despite the name). For jms/serializer-bundle the default format is `\DateTime::ATOM` (the real ISO-8601 format) but it can be changed in [configuration](https://jmsyst.com/bundles/JMSSerializerBundle/master/configuration#configuration-block-2-0).
  335. Examples:
  336. .. code-block :: php
  337. <?php
  338. namespace MyNamespace;
  339. use JMS\Serializer\Annotation\Type;
  340. class BlogPost
  341. {
  342. /**
  343. * @Type("ArrayCollection<MyNamespace\Comment>")
  344. */
  345. private $comments;
  346. /**
  347. * @Type("string")
  348. */
  349. private $title;
  350. /**
  351. * @Type("MyNamespace\Author")
  352. */
  353. private $author;
  354. /**
  355. * @Type("DateTime")
  356. */
  357. private $startAt;
  358. /**
  359. * @Type("DateTime<'Y-m-d'>")
  360. */
  361. private $endAt;
  362. /**
  363. * @Type("DateTimeImmutable")
  364. */
  365. private $createdAt;
  366. /**
  367. * @Type("DateTimeImmutable<'Y-m-d'>")
  368. */
  369. private $updatedAt;
  370. /**
  371. * @Type("boolean")
  372. */
  373. private $published;
  374. /**
  375. * @Type("array<string, string>")
  376. */
  377. private $keyValueStore;
  378. }
  379. @XmlRoot
  380. ~~~~~~~~
  381. This allows you to specify the name of the top-level element.
  382. .. code-block :: php
  383. <?php
  384. use JMS\Serializer\Annotation\XmlRoot;
  385. /** @XmlRoot("user") */
  386. class User
  387. {
  388. private $name = 'Johannes';
  389. }
  390. Resulting XML:
  391. .. code-block :: xml
  392. <user>
  393. <name><![CDATA[Johannes]]></name>
  394. </user>
  395. .. note ::
  396. @XmlRoot only applies to the root element, but is for example not taken into
  397. account for collections. You can define the entry name for collections using
  398. @XmlList, or @XmlMap.
  399. @XmlAttribute
  400. ~~~~~~~~~~~~~
  401. This allows you to mark properties which should be set as attributes,
  402. and not as child elements.
  403. .. code-block :: php
  404. <?php
  405. use JMS\Serializer\Annotation\XmlAttribute;
  406. class User
  407. {
  408. /** @XmlAttribute */
  409. private $id = 1;
  410. private $name = 'Johannes';
  411. }
  412. Resulting XML:
  413. .. code-block :: xml
  414. <result id="1">
  415. <name><![CDATA[Johannes]]></name>
  416. </result>
  417. @XmlDiscriminator
  418. ~~~~~~~~~~~~~~~~~
  419. This annotation allows to modify the behaviour of @Discriminator regarding handling of XML.
  420. Available Options:
  421. +-------------------------------------+--------------------------------------------------+
  422. | Type | Description |
  423. +=====================================+==================================================+
  424. | attribute | use an attribute instead of a child node |
  425. +-------------------------------------+--------------------------------------------------+
  426. | cdata | render child node content with or without cdata |
  427. +-------------------------------------+--------------------------------------------------+
  428. | namespace | render child node using the specified namespace |
  429. +-------------------------------------+--------------------------------------------------+
  430. Example for "attribute":
  431. .. code-block :: php
  432. <?php
  433. use JMS\Serializer\Annotation\Discriminator;
  434. use JMS\Serializer\Annotation\XmlDiscriminator;
  435. /**
  436. * @Discriminator(field = "type", map = {"car": "Car", "moped": "Moped"}, groups={"foo", "bar"})
  437. * @XmlDiscriminator(attribute=true)
  438. */
  439. abstract class Vehicle { }
  440. class Car extends Vehicle { }
  441. Resulting XML:
  442. .. code-block :: xml
  443. <vehicle type="car" />
  444. Example for "cdata":
  445. .. code-block :: php
  446. <?php
  447. use JMS\Serializer\Annotation\Discriminator;
  448. use JMS\Serializer\Annotation\XmlDiscriminator;
  449. /**
  450. * @Discriminator(field = "type", map = {"car": "Car", "moped": "Moped"}, groups={"foo", "bar"})
  451. * @XmlDiscriminator(attribute=true)
  452. */
  453. abstract class Vehicle { }
  454. class Car extends Vehicle { }
  455. Resulting XML:
  456. .. code-block :: xml
  457. <vehicle><type>car</type></vehicle>
  458. @XmlValue
  459. ~~~~~~~~~
  460. This allows you to mark properties which should be set as the value of the
  461. current element. Note that this has the limitation that any additional
  462. properties of that object must have the @XmlAttribute annotation.
  463. XMlValue also has property cdata. Which has the same meaning as the one in
  464. XMLElement.
  465. .. code-block :: php
  466. <?php
  467. use JMS\Serializer\Annotation\XmlAttribute;
  468. use JMS\Serializer\Annotation\XmlValue;
  469. use JMS\Serializer\Annotation\XmlRoot;
  470. /** @XmlRoot("price") */
  471. class Price
  472. {
  473. /** @XmlAttribute */
  474. private $currency = 'EUR';
  475. /** @XmlValue */
  476. private $amount = 1.23;
  477. }
  478. Resulting XML:
  479. .. code-block :: xml
  480. <price currency="EUR">1.23</price>
  481. @XmlList
  482. ~~~~~~~~
  483. This allows you to define several properties of how arrays should be
  484. serialized. This is very similar to @XmlMap, and should be used if the
  485. keys of the array are not important.
  486. .. code-block :: php
  487. <?php
  488. use JMS\Serializer\Annotation\XmlList;
  489. use JMS\Serializer\Annotation\XmlRoot;
  490. /** @XmlRoot("post") */
  491. class Post
  492. {
  493. /**
  494. * @XmlList(inline = true, entry = "comment")
  495. */
  496. private $comments = array(
  497. new Comment('Foo'),
  498. new Comment('Bar'),
  499. );
  500. }
  501. class Comment
  502. {
  503. private $text;
  504. public function __construct($text)
  505. {
  506. $this->text = $text;
  507. }
  508. }
  509. Resulting XML:
  510. .. code-block :: xml
  511. <post>
  512. <comment>
  513. <text><![CDATA[Foo]]></text>
  514. </comment>
  515. <comment>
  516. <text><![CDATA[Bar]]></text>
  517. </comment>
  518. </post>
  519. You can also specify the entry tag namespace using the ``namespace`` attribute (``@XmlList(inline = true, entry = "comment", namespace="http://www.example.com/ns")``).
  520. @XmlMap
  521. ~~~~~~~
  522. Similar to @XmlList, but the keys of the array are meaningful.
  523. @XmlKeyValuePairs
  524. ~~~~~~~~~~~~~~~~~
  525. This allows you to use the keys of an array as xml tags.
  526. .. note ::
  527. When a key is an invalid xml tag name (e.g. 1_foo) the tag name *entry* will be used instead of the key.
  528. @XmlAttributeMap
  529. ~~~~~~~~~~~~~~~~
  530. This is similar to the @XmlKeyValuePairs, but instead of creating child elements, it creates attributes.
  531. .. code-block :: php
  532. <?php
  533. use JMS\Serializer\Annotation\XmlAttribute;
  534. class Input
  535. {
  536. /** @XmlAttributeMap */
  537. private $id = array(
  538. 'name' => 'firstname',
  539. 'value' => 'Adrien',
  540. );
  541. }
  542. Resulting XML:
  543. .. code-block :: xml
  544. <result name="firstname" value="Adrien"/>
  545. @XmlElement
  546. ~~~~~~~~~~~
  547. This annotation can be defined on a property to add additional xml serialization/deserialization properties.
  548. .. code-block :: php
  549. <?php
  550. use JMS\Serializer\Annotation\XmlElement;
  551. /**
  552. * @XmlNamespace(uri="http://www.w3.org/2005/Atom", prefix="atom")
  553. */
  554. class User
  555. {
  556. /**
  557. * @XmlElement(cdata=false, namespace="http://www.w3.org/2005/Atom")
  558. */
  559. private $id = 'my_id';
  560. }
  561. Resulting XML:
  562. .. code-block :: xml
  563. <atom:id>my_id</atom:id>
  564. @XmlNamespace
  565. ~~~~~~~~~~~~~
  566. This annotation allows you to specify Xml namespace/s and prefix used.
  567. .. code-block :: php
  568. <?php
  569. use JMS\Serializer\Annotation\XmlNamespace;
  570. /**
  571. * @XmlNamespace(uri="http://example.com/namespace")
  572. * @XmlNamespace(uri="http://www.w3.org/2005/Atom", prefix="atom")
  573. */
  574. class BlogPost
  575. {
  576. /**
  577. * @Type("JMS\Serializer\Tests\Fixtures\Author")
  578. * @Groups({"post"})
  579. * @XmlElement(namespace="http://www.w3.org/2005/Atom")
  580. */
  581. private $author;
  582. }
  583. class Author
  584. {
  585. /**
  586. * @Type("string")
  587. * @SerializedName("full_name")
  588. */
  589. private $name;
  590. }
  591. Resulting XML:
  592. .. code-block :: xml
  593. <?xml version="1.0" encoding="UTF-8"?>
  594. <blog-post xmlns="http://example.com/namespace" xmlns:atom="http://www.w3.org/2005/Atom">
  595. <atom:author>
  596. <full_name><![CDATA[Foo Bar]]></full_name>
  597. </atom:author>
  598. </blog>