custom.rst 7.4 KB

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