PHP8.0新特性之Attributes(注解)
说起注解,有没有想起注释?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
我是温新
每天进步一点,就一点点
请登录后再评论