PHP8.0新特性之Attributes(注解)

作者: 温新

分类: 【PHP基础】

阅读: 3398

时间: 2022-01-25 09:16:32

说起注解,有没有想起注释?PHP8.0之前的注释,除了说明代码的作用外没有任何其它含义。下面来看看PHP8.0之前的代码注释:

/**
 * @param string $name
 * @param int $age
 **/
function show($name, $age) {}

这个函数的注释只是说明了这个函数参数的意思,注释中@param没有任何意义。如果需要对注释进行分析,可以采用截取字符串的方法,但是,对于注释,没有一个统一的标准,很容易出错。简单的记成注解就是对注释的操作。

注解 #[]

注解语法

注解是语法,而不是注释。注解有如下几种形式:

语法:#[]

#[Name]
#[Name1, Name2,...]
#[Name(Arguments)]
#[Name(Arguments1, Arguments2, ArgumentsN)]
#[Name1(Arguments), Name2(Arguments)]

注解类型

TARGET_CLASS    //类的注解类
TARGET_FUNCTION //函数注解类
TARGET_METHOD   //方法注解类
TARGET_PROPERTY //属性注解类
TARGET_CLASS_CONSTANT //类常量注解类
TARGET_PARAMETER //参数注解类
TARGET_ALL 

使用注解三步走:

1)定义注解

2)使用注解

3)提取注释

基础案例

案例一:只有注解名

#[url]
function show() {
    // 定义一个函数
    // 其注释使用注解来表示
}

// 使用反射获取注释信息
// 1、实例化函数反射类并传递函数名
$ref = new ReflectionFunction('show');
print_r($ref);
// 2、获取函数注解属性对象
$attr = $ref->getAttributes()[0];
// 3、获取注解名
print_r($attr->getName());	// 输出 url

案例二:带有参数

#[url('demo.com/id/10')]
function show() {
    // 定义一个函数
    // 其注释使用注解来表示
}

$ref = new ReflectionFunction('show');
$attr = $ref->getAttributes()[0];
echo $attr->getName();
// 获取参数
print_r($attr->getArguments()); // 数组格式

注解案例

案例一:多个注解,对应着多个注解属性对象

#[url('demo.com/id/10'), param('name')]
function show() {}


$ref = new ReflectionFunction('show');
$attr = $ref->getAttributes();
print_r($attr);
// 输出结果如下:
Array
(
    [0] => ReflectionAttribute Object
        (
            // 该对象对应着 url注解
        )
    [1] => ReflectionAttribute Object
        (
            // 该对象对应着 param注解
        )
)

案例二:注解中参数为数组

#[url('api/user/1', methods:['GET'])]
function getName($id) {}


$ref  = new ReflectionFunction('getName');
$attr = $ref->getAttributes()[0];
echo $attr->getName();
// 获取参数,其中methods为数组
print_r($attr->getArguments());

// 输出结果如下
url
Array (
    [0] => api/user/1
    [methods] => Array
        (
            [0] => GET
        )
)

案例三:注解类型的使用

注解参数的使用

// 1、注解的目标为类或者函数
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_FUNCTION)]
class Person
{
    public function __construct(string $name, int $age)
    {
        // 5、输出结果,api/user/1 10
        echo $name, $age;
    }
}

// 2、注解函数
#[Person('api/user/1', 10)]
function getPerson() {}

// 3、解析注解
$ref = new ReflectionFunction('getPerson');
$attr = $ref->getAttributes()[0];
// 4、实例化该注解函数
$attr->newInstance();

第一步:为Person声明了一个名为Attribute的直接,其指向的注解目标指向一个函数

第二步:定义一个函数,其注解名为Person(此时,注解名必须和类名保持一致);

第三步:使用反射获取注解相关信息

第四步:调用值的实例化对象(此时会将注解中的参数传递给 Person类)

第五步:Person中接收 getPerson 函数传递的值

方法的使用

上面的案例是对参数值的使用,下面学习对方法的使用,改造上面的案例

#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_FUNCTION)]
class Person
{
    public string $name;
    public int $age;

    public function __construct(string $name, int $age)
    {
        $this->name = $name;
        $this->age  = $age;
    }

    public function say()
    {
        echo $this->name, $this->age;
    }
}


#[Person('api/user/1', 10)]
function getPerson() {}

$ref = new ReflectionFunction('getPerson');
$attr = $ref->getAttributes()[0];

// 返回值是一个对象,且对象是Person
$obj = $attr->newInstance();
var_dump($obj);
// 方法调用
$obj->say();

参考资料:

https://www.php.net/releases/8.0/en.php

https://www.laruence.com/2020/06/12/5902.html

https://blog.csdn.net/qq_31725391/article/details/113436973

我是温新

每天进步一点,就一点点

请登录后再评论