| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 | Custom Annotation Classes=========================If you want to define your own annotations, you just have to group themin a namespace and register this namespace in the ``AnnotationRegistry``.Annotation classes have to contain a class-level docblock with the text``@Annotation``:.. code-block:: php    namespace MyCompany\Annotations;    /** @Annotation */    class Bar    {        // some code    }Inject annotation values------------------------The annotation parser checks if the annotation constructor has arguments,if so then it will pass the value array, otherwise it will try to injectvalues into public properties directly:.. code-block:: php    namespace MyCompany\Annotations;    /**     * @Annotation     *     * Some Annotation using a constructor     */    class Bar    {        private $foo;        public function __construct(array $values)        {            $this->foo = $values['foo'];        }    }    /**     * @Annotation     *     * Some Annotation without a constructor     */    class Foo    {        public $bar;    }Optional: Constructors with Named Parameters--------------------------------------------Starting with Annotations v1.11 a new annotation instantiation strategyis available that aims at compatibility of Annotation classes with the PHP 8attribute feature. You need to declare a constructor with regular parameter names that match the named arguments in the annotation syntax.To enable this feature, you can tag your annotation class with ``@NamedArgumentConstructor`` (available from v1.12) or implement the``Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation`` interface(available from v1.11 and deprecated as of v1.12).When using the ``@NamedArgumentConstructor`` tag, the first argument of theconstructor is considered as the default one.Usage with the ``@NamedArgumentConstructor`` tag.. code-block:: php    namespace MyCompany\Annotations;    /**      * @Annotation      * @NamedArgumentConstructor     */    class Bar implements NamedArgumentConstructorAnnotation    {        private $foo;        public function __construct(string $foo)        {            $this->foo = $foo;        }    }    /** Usable with @Bar(foo="baz") */    /** Usable with @Bar("baz") */In combination with PHP 8's constructor property promotion featureyou can simplify this to:.. code-block:: php    namespace MyCompany\Annotations;    /**      * @Annotation      * @NamedArgumentConstructor     */    class Bar implements NamedArgumentConstructorAnnotation    {        public function __construct(private string $foo) {}    }Usage with the ``Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation``interface (v1.11, deprecated as of v1.12):.. code-block:: php    namespace MyCompany\Annotations;    use Doctrine\Common\Annotations\NamedArgumentConstructorAnnotation;    /** @Annotation */    class Bar implements NamedArgumentConstructorAnnotation    {        private $foo;        public function __construct(private string $foo) {}    }    /** Usable with @Bar(foo="baz") */Annotation Target-----------------``@Target`` indicates the kinds of class elements to which an annotationtype is applicable. Then you could define one or more targets:-  ``CLASS`` Allowed in class docblocks-  ``PROPERTY`` Allowed in property docblocks-  ``METHOD`` Allowed in the method docblocks-  ``FUNCTION`` Allowed in function dockblocks-  ``ALL`` Allowed in class, property, method and function docblocks-  ``ANNOTATION`` Allowed inside other annotationsIf the annotations is not allowed in the current context, an``AnnotationException`` is thrown... code-block:: php    namespace MyCompany\Annotations;    /**     * @Annotation     * @Target({"METHOD","PROPERTY"})     */    class Bar    {        // some code    }    /**     * @Annotation     * @Target("CLASS")     */    class Foo    {        // some code    }Attribute types---------------The annotation parser checks the given parameters using the phpdocannotation ``@var``, The data type could be validated using the ``@var``annotation on the annotation properties or using the ``@Attributes`` and``@Attribute`` annotations.If the data type does not match you get an ``AnnotationException``.. code-block:: php    namespace MyCompany\Annotations;    /**     * @Annotation     * @Target({"METHOD","PROPERTY"})     */    class Bar    {        /** @var mixed */        public $mixed;        /** @var boolean */        public $boolean;        /** @var bool */        public $bool;        /** @var float */        public $float;        /** @var string */        public $string;        /** @var integer */        public $integer;        /** @var array */        public $array;        /** @var SomeAnnotationClass */        public $annotation;        /** @var array<integer> */        public $arrayOfIntegers;        /** @var array<SomeAnnotationClass> */        public $arrayOfAnnotations;    }    /**     * @Annotation     * @Target({"METHOD","PROPERTY"})     * @Attributes({     *   @Attribute("stringProperty", type = "string"),     *   @Attribute("annotProperty",  type = "SomeAnnotationClass"),     * })     */    class Foo    {        public function __construct(array $values)        {            $this->stringProperty = $values['stringProperty'];            $this->annotProperty = $values['annotProperty'];        }        // some code    }Annotation Required-------------------``@Required`` indicates that the field must be specified when theannotation is used. If it is not used you get an ``AnnotationException``stating that this value can not be null.Declaring a required field:.. code-block:: php    /**     * @Annotation     * @Target("ALL")     */    class Foo    {        /** @Required */        public $requiredField;    }Usage:.. code-block:: php    /** @Foo(requiredField="value") */    public $direction;                  // Valid     /** @Foo */    public $direction;                  // Required field missing, throws an AnnotationExceptionEnumerated values------------------ An annotation property marked with ``@Enum`` is a field that accepts a  fixed set of scalar values.- You should use ``@Enum`` fields any time you need to represent fixed  values.- The annotation parser checks the given value and throws an  ``AnnotationException`` if the value does not match.Declaring an enumerated property:.. code-block:: php    /**     * @Annotation     * @Target("ALL")     */    class Direction    {        /**         * @Enum({"NORTH", "SOUTH", "EAST", "WEST"})         */        public $value;    }Annotation usage:.. code-block:: php    /** @Direction("NORTH") */    public $direction;                  // Valid value     /** @Direction("NORTHEAST") */    public $direction;                  // Invalid value, throws an AnnotationExceptionConstants---------The use of constants and class constants is available on the annotationsparser.The following usages are allowed:.. code-block:: php    namespace MyCompany\Entity;    use MyCompany\Annotations\Foo;    use MyCompany\Annotations\Bar;    use MyCompany\Entity\SomeClass;    /**     * @Foo(PHP_EOL)     * @Bar(Bar::FOO)     * @Foo({SomeClass::FOO, SomeClass::BAR})     * @Bar({SomeClass::FOO_KEY = SomeClass::BAR_VALUE})     */    class User    {    }Be careful with constants and the cache !.. note::    The cached reader will not re-evaluate each time an annotation is    loaded from cache. When a constant is changed the cache must be    cleaned.Usage-----Using the library API is simple. Using the annotations described in theprevious section, you can now annotate other classes with yourannotations:.. code-block:: php    namespace MyCompany\Entity;    use MyCompany\Annotations\Foo;    use MyCompany\Annotations\Bar;    /**     * @Foo(bar="foo")     * @Bar(foo="bar")     */    class User    {    }Now we can write a script to get the annotations above:.. code-block:: php    $reflClass = new ReflectionClass('MyCompany\Entity\User');    $classAnnotations = $reader->getClassAnnotations($reflClass);    foreach ($classAnnotations AS $annot) {        if ($annot instanceof \MyCompany\Annotations\Foo) {            echo $annot->bar; // prints "foo";        } else if ($annot instanceof \MyCompany\Annotations\Bar) {            echo $annot->foo; // prints "bar";        }    }You have a complete API for retrieving annotation class instances from aclass, property or method docblock:Reader API~~~~~~~~~~Access all annotations of a class^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getClassAnnotations(\ReflectionClass $class);Access one annotation of a class^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getClassAnnotation(\ReflectionClass $class, $annotationName);Access all annotations of a method^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getMethodAnnotations(\ReflectionMethod $method);Access one annotation of a method^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName);Access all annotations of a property^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getPropertyAnnotations(\ReflectionProperty $property);Access one annotation of a property^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);Access all annotations of a function^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getFunctionAnnotations(\ReflectionFunction $property);Access one annotation of a function^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.. code-block:: php    public function getFunctionAnnotation(\ReflectionFunction $property, $annotationName);
 |