php注解

2021-10-15

php8可使用

  1. 注解功能使得代码中的声明部分都可以添加结构化、机器可读的元数据。
  2. 注解的目标可以是类、方法、函数、参数、属性、类常量。 通过反射API可在运行时获取注解所定义的元数据。 因此注解可以成为直接嵌入代码的配置式语言。
  3. 通过注解的使用,在应用中实现功能、使用功能可以相互解耦
  4. 通过反射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读取注解

  1. 使用getAttributes()方法, 类、方法、函数、参数、属性、类常量的反射对象可通过它获取相应的注解。该方法返回了ReflectionAttribute实例的数组,可用于查询注解名称、参数、也可以实例化一个注解
  2. 实例和反射注解的分离使得程序员增加了在丢失反射类、类型错误、丢失参数等情况下的处理能力,也能处理错误。 只有调用 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)
}
*/
{/if}