什么是注解什么是注释?
注解
与 注释
的区别:
- 注释:给程序员看,帮助理解代码,对代码起到解释、说明的作用。
- 注解:给应用程序看,用于元数据的定义,单独使用时没有任何作用,需配合应用程序对其元数据进行利用才有作用。
PHP
语法本身并没有实支持注解
,实现注解只能从注释中解析。
Hyperf 使用注解的几种方式
- 类
- 类方法
- 类属性
创建注解
自定义注解
在 Hyperf 项目 app
目录中创建一个 Annotation
文件夹
比如创建一个 User
类,那么位置就是 app\Annotation\User.php
类注解
namespace App\Annotation;
<?php
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target("CLASS")
*/
class User extends AbstractAnnotation
{
}
方法注解
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target("METHOD")
*/
class User extends AbstractAnnotation
{
}
类成员属性注解
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target("PROPERTY")
*/
class User extends AbstractAnnotation
{
}
或者默认支持以上三种所有注解
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target("ALL")
*/
class User extends AbstractAnnotation
{
}
数组方式
假如同时想要支持
METHOD
和CLASS
两种注解,那么就可以采用{"CLASS","METHOD"}
这种方式
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target({"CLASS","METHOD"})
*/
class User extends AbstractAnnotation
{
}
@Target 主要用于指定该注解默认的级别是 类注解、还是方法、或者是类成员属性
可以看到定义注解其实就是在 注释上增加两个类似 "方法" 的东西
注意注解类的 @Annotation 和 @Target 注解为全局注解,所以无需 use ,引入命名空间
注解参数传递
假如注解需要接收参数该怎么处理呢?在注解中定义一个属性
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target({"CLASS","METHOD"})
*/
class User extends AbstractAnnotation
{
/**
* @var string
*/
public $name;
}
自定义注解收集器
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AnnotationInterface;
/**
* @Annotation
* @Target({"CLASS","METHOD","PROPERTY"})
*/
class User implements AnnotationInterface
{
/**
* @var string
*/
public $name;
/**
* Collect the annotation metadata to a container that you wants.
*/
public function collectClass(string $className): void
{
// TODO: Implement collectClass() method.
}
/**
* Collect the annotation metadata to a container that you wants.
*/
public function collectMethod(string $className, ?string $target): void
{
// TODO: Implement collectMethod() method.
}
/**
* Collect the annotation metadata to a container that you wants.
*/
public function collectProperty(string $className, ?string $target): void
{
// TODO: Implement collectProperty() method.
}
}
使用注解
上面我们定义注解,是支持三种方式, CLASS
、METHOD
、PROPERTY
,所有使用也是这三种方式
我们用 IndexController 来测试,注解是否可以正确接收参数
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Annotation\User;
use Hyperf\Di\Annotation\AnnotationCollector;
use Hyperf\HttpServer\Annotation\AutoController;
/**
* @AutoController()
* @User(name="123")
*/
class IndexController extends Controller
{
public function index()
{
var_dump(AnnotationCollector::getClassByAnnotation(User::class));
return 'Hello Hyperf!';
}
}
然后请求下地址 http://127.0.0.1:9501/index/index
路由。
控制台会直接返回
我们这是采用字符串的参数传递,但是看文档还有一种直接传递值的方法,我们来试下,看能不能正确接收.
...
/**
* @AutoController()
* @User("123")
*/
class IndexController extends Controller
{
public function index()
{
var_dump(AnnotationCollector::getClassByAnnotation(User::class));
return 'Hello Hyperf!';
}
}
然后再次请求下地址,看有没有正确接收值。我们看到注解并没有接收到这个值.
那么到底该怎样接收这个值呢?重写我们的注解类,重写构造函数 ,注解类有一个 设置主属性的方式。
<?php
namespace App\Annotation;
use Hyperf\Di\Annotation\AbstractAnnotation;
/**
* @Annotation
* @Target({"CLASS","METHOD"})
*/
class User extends AbstractAnnotation
{
/**
* @var string
*/
public $name;
public function __construct($value = null)
{
parent::__construct($value);
$this->bindMainProperty('name',$value);
}
}
再次请求下地址,即可返回
关于极客返利
极客返利 是由我个人开发的一款网课返利、返现平台。包含 极客时间返现、拉勾教育返现、掘金小册返现、GitChat返现。目前仅包含这几个平台。后续如果有需要可以考虑其他平台。 简而言之就是:你买课,我返现。让你花更少的钱,就可以买到课程。
版权许可
本作品采用 知识共享署名 4.0 国际许可协议 进行许可。转载无需与我联系,但须注明出处,注明文章来源 Hyperf 初体验-注解