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