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