egorov / yii2-annotations
允许你在Yii2项目中使用doctrine/annotations
Requires
- php: ^7.1
- doctrine/annotations: ^1.10
Requires (Dev)
- phpstan/phpstan: @stable
- phpunit/phpunit: ~7
- roave/security-advisories: dev-master
- squizlabs/php_codesniffer: @stable
- yiisoft/yii2-dev: ~2.0.14
This package is auto-updated.
Last update: 2024-09-16 00:33:31 UTC
README
Yii2 Annotations 扩展
使用Yii2缓存驱动程序在Yii2项目中使用 doctrine/annotations
安装
composer require egorov/yii2-annotations
配置
...
'components' => [
'annotations' => [
'class' => 'yii\annotations\Annotations',
'cache' => '\yii\caching\FileCache',
'path' => '@runtime/annotations',
'debug' => false,
'ignoreAnnotations' => [
'properties', 'relations', 'property'
]
]
],
...
其中
class - yii\annotations\Annotations class or class implementing yii\annotations\AnnotationsInterface,
cache - Optional. Container with cache component defined in configuration or cache class. By default 'cache',
path - Optional. Annotations cache dir for \yii\caching\FileCache,
debug - Optional boolean. Debug enable. True means that the cache will be invalid every time the file is changed, false - the cache will be generated once
ignoreAnnotations - List of ignored annotations when parsing a file
注解类
注解类必须包含包含文本 @Annotation 的类级别 docblock
/** @Annotation */
class Bar
{
// some code
}
注入注解值
注解解析器检查注解构造函数是否有参数,如果有,则传递值数组,否则将尝试直接将值注入到公共属性中
/**
* @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;
}
注解目标
@Target 表示注解类型适用于哪些类元素的类型。然后你可以定义一个或多个目标
CLASS 在类 docblock 中允许 PROPERTY 在属性 docblock 中允许 METHOD 在方法 docblock 中允许 ALL 在类、属性和方法 docblock 中允许 ANNOTATION 在其他注解内部允许 如果注解不允许在当前上下文中,您将收到 AnnotationException
/**
* @Annotation
* @Target({"METHOD","PROPERTY"})
*/
class Bar
{
// some code
}
/**
* @Annotation
* @Target("CLASS")
*/
class Foo
{
// some code
}
属性类型
注解解析器使用 phpdoc 注释 @var 检查给定的参数,数据类型可以使用注解属性上的 @var 注释或使用 @Attributes 和 @Attribute 注解进行验证
如果数据类型不匹配,您将收到 AnnotationException
/**
* @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
}
注解必需
@Required 表示当使用注解时必须指定字段。如果没有使用,则获取 AnnotationException,指出此值不能为空。
声明必需字段
/**
* @Annotation
* @Target("ALL")
*/
class Foo
{
/** @Required */
public $requiredField;
}
用法
/** @Foo(requiredField="value") */
public $direction; // Valid
/** @Foo */
public $direction; // Required field missing, throws an AnnotationException
枚举值
带有 @Enum 标记的注解属性是一个接受固定标量值集合的字段。您应该在任何需要表示固定值的情况下使用 @Enum 字段。注解解析器检查给定的值,并在值不匹配时抛出 AnnotationException。声明枚举属性
/**
* @Annotation
* @Target("ALL")
*/
class Direction
{
/**
* @Enum({"NORTH", "SOUTH", "EAST", "WEST"})
*/
public $value;
}
注解用法
/** @Direction("NORTH") */
public $direction; // Valid value
/** @Direction("NORTHEAST") */
public $direction; // Invalid value, throws an AnnotationException
常量
在注解解析器中可以使用常量和类常量。
以下使用方式是被允许的:
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
{
}
请注意常量和缓存!
缓存读取器在从缓存中加载每个注解时不会重新评估。当常量更改时,必须清理缓存。
使用示例
创建注解类
<?php
/**
* @Annotation
* @Target({"CLASS"})
*/
class ServiceDescription
{
/** @var string */
private $description;
/** @var array<ServiceMethod> */
private $methods;
public function __construct(array $values)
{
$this->description = $values['description'] ?? [];
$this->methods = $values['methods'] ?? [];
}
}
<?php
/**
* @Annotation
* @Target({"CLASS", "ANNOTATION"})
*/
class ServiceMethod
{
/** @var string */
private $name;
/** @var string */
private $description;
public function __construct(array $values)
{
$this->name = $values['name'];
$this->description = $values['description'];
}
}
在目标类中编写注解
...
/**
* Class ReportDataService
* @ServiceDescription(
* description = "Service description",
* methods = {
* @ServiceMethod(
* name="delete",
* description="delete ReportData method description"
* ),
* @ServiceMethod(
* name="getAll",
* description="getAll ReportData method description"
* ),
* @ServiceMethod(
* name="update",
* description="update ReportData method description"
* ),
* @ServiceMethod(
* name="count",
* description="count ReportData method description"
* )
* }
* )
*/
class ReportDataService extends BaseModelService
...
<?php
...
$reader = Yii::$app->annotations->getReader();
...
读取器API
访问类的所有注解
$reader->getClassAnnotations(\ReflectionClass $class);
访问类的一个注解
$reader->getClassAnnotation(\ReflectionClass $class, $annotationName);
访问方法的所有注解
$reader->getMethodAnnotations(\ReflectionMethod $method);
访问方法的一个注解
$reader->getMethodAnnotation(\ReflectionMethod $method, $annotationName);
访问属性的所有注解
$reader->getPropertyAnnotations(\ReflectionProperty $property);
访问属性的一个注解
$reader->getPropertyAnnotation(\ReflectionProperty $property, $annotationName);
获取解析器
直接从docBlock解析注解。它不会被缓存
<?php
...
$reader = Yii::$app->annotations->getParser([
'annotationName' => AnnotationClass::class
]);
...