Advanced featuresMultiple instances of annotationsYou can place multiple instances of same class annotations on one target. /**
@Title(value='Welcome', lang='en')
@Title(value='Wilkommen', lang='de')
@Title(value='Vitajte', lang='sk')
@Snippet
*/
class WelcomeScreen {}And then access them using $reflection = new ReflectionAnnotatedClass('WelcomeScreen');
$annotations = $reflection->getAllAnnotations(); // array of all 4 annotations
$just_titles = $reflection->getAllAnnotations('Title'); // array of those 3 Title annotationsConstrained annotationsMeta-annotation @TargetUsing @Target meta-annotation you can easily annotate annotations (yes, it's kind of scary!) to prevent annotations to be misplaced. For example you might want a @Route annotation that can be only used to annotate methods. It's easy: /** @Target("method") */
class Route extends Annotation {}Besides "method" target definition you can also use "class", "property" and "nested". Implementing custom constraintsSometimes @Target meta-annotation does not provide enough power to check for additional constraints. You can override Annotation::checkConstraints method to add additional rules for validation, etc. class Route extends Annotation {
protected function checkConstraints($target) {
if($this->value == /* something bad */) {
// trigger some error
} else {
// do something else
}
// variable $target holds reflection class of annotation target (class, method, property)
}
}Nested annotationsAs if it were not enough, even annotations can be nested inside each other. Look at this: /** @Mapping(inheritance = @SingleTableInheritance, columns = {@ColumnMapping('id'), @ColumnMapping('name')}) */
class Person {}
$reflection = new ReflectionAnnotatedClass('Person');
$annotation = $reflection->getAnnotation('Mapping');
$annotation->inheritance; // SingleTableInheritance annotation
$annotation->columns; // array of ColumnMapping annotations
$annotation->columns[0]->value; // 'id'If you want to ensure that your @ColumnMapping annotation should be only used in nested contexts, add @Target meta-annotation with "nested". /** @Target("nested") */
class ColumnMapping extends Annotation {}Annotation class name resolvingIf you use prefixed annotation class names like MyDoomdayProject_God. You can save yourself a few keystrokes by using: class MyDoomsdayProject_God extends Annotation {}
/** @God */
class Me {}
$reflection = new ReflectionAnnotatedClass('Me');
$reflection->getAnnotation('God'); // returns MyDoomsdayProject_GodDid you notice that Addendum automatically resolves @God annotation into @MyDoomsdayProject_God annotation? And of course you can also use the full class name.
|