php8可使用
- 注解功能使得代码中的声明部分都可以添加结构化、机器可读的元数据。
- 注解的目标可以是类、方法、函数、参数、属性、类常量。 通过反射API可在运行时获取注解所定义的元数据。 因此注解可以成为直接嵌入代码的配置式语言。
- 通过注解的使用,在应用中实现功能、使用功能可以相互解耦
- 通过反射API请求注解实例时,注解的名称会被解析到一个类,注解的参数则传入该类的构造器中。因此每个注解都需要引入一个类。
注解语法
#[注解1,注解2,...]
注解名称要使用命名空间
注解类
推荐为每个注解创建一个实际的类
简单示例
<?php
namespace Example;
// 引入#[Attribute]注解所需要全空的类。
use Attribute;
#[Attribute]
class MyAttribute
{
}
为#[Attribute]注解第一个参数传入字节位掩码设置限制指定注解的声明类型
<?php
namespace Example;
use Attribute;
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class MyAttribute
{
}
允许注解在声明中出现多次
namespace Example;
use Attribute;
// 注解在每个声明中默认情况下只能使用一次,使用IS_REPEATABLE允许注解在声明中出现多次
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)]
class MyAttribute
{
}
使用反射API读取注解
- 使用getAttributes()方法, 类、方法、函数、参数、属性、类常量的反射对象可通过它获取相应的注解。该方法返回了ReflectionAttribute实例的数组,可用于查询注解名称、参数、也可以实例化一个注解
- 实例和反射注解的分离使得程序员增加了在丢失反射类、类型错误、丢失参数等情况下的处理能力,也能处理错误。 只有调用 newInstance() 后,注解类的对象才会以验证过匹配的参数来实例化
<?php
#[Attribute]
class MyAttribute
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
}
#[MyAttribute(value: 1234)]
class Thing
{
}
function dumpAttributeData($reflection) {
// 通过传入参数:待搜索的注解类名,可返回指定的注解类,而不需要再到反射类中迭代循环获取所有注解。
$attributes = $reflection->getAttributes();
foreach ($attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
var_dump($attribute->newInstance());
}
}
dumpAttributeData(new ReflectionClass(Thing::class));
/*
string(11) "MyAttribute"
array(1) {
["value"] => int(1234)
}
object(MyAttribute)#3 (1) {
["value"] => int(1234)
}
*/