custom.rst 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. Custom Annotation Classes
  2. =========================
  3. If you want to define your own annotations, you just have to group them
  4. in a namespace and register this namespace in the ``AnnotationRegistry``.
  5. Annotation classes have to contain a class-level docblock with the text
  6. ``@Annotation``:
  7. .. code-block:: php
  8. namespace MyCompany\Annotations;
  9. /** @Annotation */
  10. class Bar
  11. {
  12. // some code
  13. }
  14. Inject annotation values
  15. ------------------------
  16. The annotation parser checks if the annotation constructor has arguments,
  17. if so then it will pass the value array, otherwise it will try to inject
  18. values into public properties directly:
  19. .. code-block:: php
  20. namespace MyCompany\Annotations;
  21. /**
  22. * @Annotation
  23. *
  24. * Some Annotation using a constructor
  25. */
  26. class Bar
  27. {
  28. private $foo;
  29. public function __construct(array $values)
  30. {
  31. $this->foo = $values['foo'];
  32. }
  33. }
  34. /**
  35. * @Annotation
  36. *
  37. * Some Annotation without a constructor
  38. */
  39. class Foo
  40. {
  41. public $bar;
  42. }
  43. Annotation Target
  44. -----------------
  45. ``@Target`` indicates the kinds of class elements to which an annotation
  46. type is applicable. Then you could define one or more targets:
  47. - ``CLASS`` Allowed in class docblocks
  48. - ``PROPERTY`` Allowed in property docblocks
  49. - ``METHOD`` Allowed in the method docblocks
  50. - ``ALL`` Allowed in class, property and method docblocks
  51. - ``ANNOTATION`` Allowed inside other annotations
  52. If the annotations is not allowed in the current context, an
  53. ``AnnotationException`` is thrown.
  54. .. code-block:: php
  55. namespace MyCompany\Annotations;
  56. /**
  57. * @Annotation
  58. * @Target({"METHOD","PROPERTY"})
  59. */
  60. class Bar
  61. {
  62. // some code
  63. }
  64. /**
  65. * @Annotation
  66. * @Target("CLASS")
  67. */
  68. class Foo
  69. {
  70. // some code
  71. }
  72. Attribute types
  73. ---------------
  74. The annotation parser checks the given parameters using the phpdoc
  75. annotation ``@var``, The data type could be validated using the ``@var``
  76. annotation on the annotation properties or using the ``@Attributes`` and
  77. ``@Attribute`` annotations.
  78. If the data type does not match you get an ``AnnotationException``
  79. .. code-block:: php
  80. namespace MyCompany\Annotations;
  81. /**
  82. * @Annotation
  83. * @Target({"METHOD","PROPERTY"})
  84. */
  85. class Bar
  86. {
  87. /** @var mixed */
  88. public $mixed;
  89. /** @var boolean */
  90. public $boolean;
  91. /** @var bool */
  92. public $bool;
  93. /** @var float */
  94. public $float;
  95. /** @var string */
  96. public $string;
  97. /** @var integer */
  98. public $integer;
  99. /** @var array */
  100. public $array;
  101. /** @var SomeAnnotationClass */
  102. public $annotation;
  103. /** @var array<integer> */
  104. public $arrayOfIntegers;
  105. /** @var array<SomeAnnotationClass> */
  106. public $arrayOfAnnotations;
  107. }
  108. /**
  109. * @Annotation
  110. * @Target({"METHOD","PROPERTY"})
  111. * @Attributes({
  112. * @Attribute("stringProperty", type = "string"),
  113. * @Attribute("annotProperty", type = "SomeAnnotationClass"),
  114. * })
  115. */
  116. class Foo
  117. {
  118. public function __construct(array $values)
  119. {
  120. $this->stringProperty = $values['stringProperty'];
  121. $this->annotProperty = $values['annotProperty'];
  122. }
  123. // some code
  124. }
  125. Annotation Required
  126. -------------------
  127. ``@Required`` indicates that the field must be specified when the
  128. annotation is used. If it is not used you get an ``AnnotationException``
  129. stating that this value can not be null.
  130. Declaring a required field:
  131. .. code-block:: php
  132. /**
  133. * @Annotation
  134. * @Target("ALL")
  135. */
  136. class Foo
  137. {
  138. /** @Required */
  139. public $requiredField;
  140. }
  141. Usage:
  142. .. code-block:: php
  143. /** @Foo(requiredField="value") */
  144. public $direction; // Valid
  145. /** @Foo */
  146. public $direction; // Required field missing, throws an AnnotationException
  147. Enumerated values
  148. -----------------
  149. - An annotation property marked with ``@Enum`` is a field that accepts a
  150. fixed set of scalar values.
  151. - You should use ``@Enum`` fields any time you need to represent fixed
  152. values.
  153. - The annotation parser checks the given value and throws an
  154. ``AnnotationException`` if the value does not match.
  155. Declaring an enumerated property:
  156. .. code-block:: php
  157. /**
  158. * @Annotation
  159. * @Target("ALL")
  160. */
  161. class Direction
  162. {
  163. /**
  164. * @Enum({"NORTH", "SOUTH", "EAST", "WEST"})
  165. */
  166. public $value;
  167. }
  168. Annotation usage:
  169. .. code-block:: php
  170. /** @Direction("NORTH") */
  171. public $direction; // Valid value
  172. /** @Direction("NORTHEAST") */
  173. public $direction; // Invalid value, throws an AnnotationException
  174. Constants
  175. ---------
  176. The use of constants and class constants is available on the annotations
  177. parser.
  178. The following usages are allowed:
  179. .. code-block:: php
  180. namespace MyCompany\Entity;
  181. use MyCompany\Annotations\Foo;
  182. use MyCompany\Annotations\Bar;
  183. use MyCompany\Entity\SomeClass;
  184. /**
  185. * @Foo(PHP_EOL)
  186. * @Bar(Bar::FOO)
  187. * @Foo({SomeClass::FOO, SomeClass::BAR})
  188. * @Bar({SomeClass::FOO_KEY = SomeClass::BAR_VALUE})
  189. */
  190. class User
  191. {
  192. }
  193. Be careful with constants and the cache !
  194. .. note::
  195. The cached reader will not re-evaluate each time an annotation is
  196. loaded from cache. When a constant is changed the cache must be
  197. cleaned.
  198. Usage
  199. -----
  200. Using the library API is simple. Using the annotations described in the
  201. previous section, you can now annotate other classes with your
  202. annotations:
  203. .. code-block:: php
  204. namespace MyCompany\Entity;
  205. use MyCompany\Annotations\Foo;
  206. use MyCompany\Annotations\Bar;
  207. /**
  208. * @Foo(bar="foo")
  209. * @Bar(foo="bar")
  210. */
  211. class User
  212. {
  213. }
  214. Now we can write a script to get the annotations above:
  215. .. code-block:: php
  216. $reflClass = new ReflectionClass('MyCompany\Entity\User');
  217. $classAnnotations = $reader->getClassAnnotations($reflClass);
  218. foreach ($classAnnotations AS $annot) {
  219. if ($annot instanceof \MyCompany\Annotations\Foo) {
  220. echo $annot->bar; // prints "foo";
  221. } else if ($annot instanceof \MyCompany\Annotations\Bar) {
  222. echo $annot->foo; // prints "bar";
  223. }
  224. }
  225. You have a complete API for retrieving annotation class instances from a
  226. class, property or method docblock:
  227. Reader API
  228. ~~~~~~~~~~
  229. Access all annotations of a class
  230. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  231. .. code-block:: php
  232. public function getClassAnnotations(\ReflectionClass $class);
  233. Access one annotation of a class
  234. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  235. .. code-block:: php
  236. public function getClassAnnotation(\ReflectionClass $class, $annotationName);
  237. Access all annotations of a method
  238. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  239. .. code-block:: php
  240. public function getMethodAnnotations(\ReflectionMethod $method);
  241. Access one annotation of a method
  242. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  243. .. code-block:: php
  244. public function getMethodAnnotation(\ReflectionMethod $method, $annotationName);
  245. Access all annotations of a property
  246. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  247. .. code-block:: php
  248. public function getPropertyAnnotations(\ReflectionProperty $property);
  249. Access one annotation of a property
  250. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  251. .. code-block:: php
  252. public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);