详解php8注解

时间:2020-12-07

什么是注解?

/**
 * 类上的注解
 */
#[Route()]
class Test
{
    /**
     * 方法上的多个注解
     */
    #[Route1(),Route2()]
    public function hello()
    {
        echo 'hello';
    }
}

$test = new Test();
$test->hello();

可以在类上、方法上、属性上使用注解。可以不编写注解类使用。

什么是注解类?

注解类的使用范围

无参数的注解类

/**
 * 限定注解类的使用范围
 */
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class Route
{
    public function __contrust()
    {

    }
}

有参数的注解类

/**
 * 限定注解类的使用范围
 */
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class Route
{
    private string $url;
    private string $method;

    /**
     * @param string $url
     * @param string $method
     */
    public function __construct(string $url, string $method = 'post')
    {
        $this->url = $url;
        $this->method = strtoupper($method);

    }

    public function getUrl(): string
    {
        return $this->url;
    }

    public function getMethod(): string
    {
        return $this->method;
    }
}

使用注解类

/**
 * 类上的注解
 */
#[Route('/test1')]
class Test
{
    /**
     * 方法上的注解
     */
    #[Route('/test2',method: 'get')]
    public function hello()
    {
        echo 'hello';
    }
}

获取类上的所有注解

$testObj = new ReflectionClass(Test::class);
// 获取类上的所有注解类
$attrs = $testObj->getAttributes();
$len = count($attrs);
for ($i = 0; $i < $len; $i++) {
    // 注解名称
    echo $attrs[$i]->getName();
    echo PHP_EOL;
    // 注解上的参数,
    print_r($attrs[$i]->getArguments());
    echo PHP_EOL;
    // Returns the target of the attribute as a bit mask format
    print_r($attrs[$i]->getTarget());
    echo PHP_EOL;
}

// 获取 指定 的注解类
$attrs = $testObj->getAttributes(Route::class);
// 注解名称
echo $attrs[0]->getName();
echo PHP_EOL;
// 注解上的参数,
print_r($attrs[0]->getArguments());
echo PHP_EOL;
// Returns the target of the attribute as a bit mask format
print_r($attrs[0]->getTarget());
echo PHP_EOL;

结果一样,因为类上只用了一个注解类

获取方法上的注解

// 获取方法上的注解
$methodObj = $testObj->getMethod('hello');
// 用法同类上的注解一样,只不过把类对象换成方法对象
// 获取 指定 的注解类
$attrs = $methodObj->getAttributes(Route::class);
// 注解名称
echo $attrs[0]->getName();
echo PHP_EOL;
// 注解上的参数,
print_r($attrs[0]->getArguments());
echo PHP_EOL;
// Returns the target of the attribute as a bit mask format
print_r($attrs[0]->getTarget());
echo PHP_EOL;

获取注解对象

// 获取注解对象
$routeObj = $attrs[0]->newInstance();
// 调用注解方法
echo $routeObj->getUrl();
echo PHP_EOL;
echo $routeObj->getMethod();

完整代码

/**
 * 限定注解类的使用范围
 */
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class Route
{
    private string $url;
    private string $method;

    /**
     * @param string $url
     * @param string $method
     */
    public function __construct(string $url, string $method = 'post')
    {
        $this->url = $url;
        $this->method = strtoupper($method);

    }

    public function getUrl(): string
    {
        return $this->url;
    }

    public function getMethod(): string
    {
        return $this->method;
    }
}

/**
 * 类上的注解
 */
#[Route('/test1')]
class Test
{
    /**
     * 方法上的注解
     */
    #[Route('/test2', method: 'get')]
    public function hello()
    {
        echo 'hello';
    }
}

$testObj = new ReflectionClass(Test::class);
// 获取类上的所有注解类
$attrs = $testObj->getAttributes();
$len = count($attrs);
for ($i = 0; $i < $len; $i++) {
    // 注解名称
    echo $attrs[$i]->getName();
    echo PHP_EOL;
    // 注解上的参数,
    print_r($attrs[$i]->getArguments());
    echo PHP_EOL;
    // Returns the target of the attribute as a bit mask format
    print_r($attrs[$i]->getTarget());
    echo PHP_EOL;
}

// 获取 指定 的注解类
$attrs = $testObj->getAttributes(Route::class);
// 注解名称
echo $attrs[0]->getName();
echo PHP_EOL;
// 注解上的参数,
print_r($attrs[0]->getArguments());
echo PHP_EOL;
// Returns the target of the attribute as a bit mask format
print_r($attrs[0]->getTarget());
echo PHP_EOL;

// 获取方法上的注解
$methodObj = $testObj->getMethod('hello');
// 用法同类上的注解一样,只不过把类对象换成方法对象
// 获取 指定 的注解类
$attrs = $methodObj->getAttributes(Route::class);
// 注解名称
echo $attrs[0]->getName();
echo PHP_EOL;
// 注解上的参数,
print_r($attrs[0]->getArguments());
echo PHP_EOL;
// Returns the target of the attribute as a bit mask format
print_r($attrs[0]->getTarget());
echo PHP_EOL;

// 获取注解对象
$routeObj = $attrs[0]->newInstance();
// 调用注解方法
echo $routeObj->getUrl();
echo PHP_EOL;
echo $routeObj->getMethod();