1.定义
注解功能使得代码中的声明部分都可以添加结构化、机器可读的元数据, 注解的目标可以是类、方法、函数、参数、属性、类常量。 通过 反射 API 可在运行时获取注解所定义的元数据。 因此注解可以成为直接嵌入代码的配置式语言。
通过注解的使用,在应用中实现功能、使用功能可以相互解耦。 某种程度上讲,它可以和接口(interface)与其实现(implementation)相比较。 但接口与实现是代码相关的,注解则与声明额外信息和配置相关。 接口可以通过类来实现,而注解也可以声明到方法、函数、参数、属性、类常量中。 因此它们比接口更灵活。
注解使用的一个简单例子:将接口(interface)的可选方法改用注解实现。 我们假设接口 ActionHandler 代表了应用的一个操作: 部分 action handler 的实现需要 setup,部分不需要。 我们可以使用注解,而不用要求所有类必须实现 ActionHandler 接口并实现 setUp() 方法。 因此带来一个好处——可以多次使用注解。
2.两种方式
1.PHP8新增了attribute注解类
2.以前的版本Doctrine Annotations
composer require doctrine/annotations
中文使用文档
3.原理
1.注解的使用
/**
* 列表及搜索
* @funcName 院所管理-院所列表
*/
public function index()
{
//如果是搜索,转换成GET方式,以便以后后退
if ($_POST) {
$this->redirect($this->url(SFrame::getController(), SFrame::getAction(), $_POST));
}
以上是自己定义的一个注解 funcName, 用来标识一个功能的名称
//反射
$m = new ReflectionMethod($this, $name);
//方法注释
$note = mid(trim($m . ''), '/**', '*/');
//取指定标签 funcName 的值
$matched = preg_match('/@funcName\s*([^\s]*)/i', $note, $matches);
以上只是示例, 通过反射得到代码的注释,正则取到指定注解的值, 然后自己来 根据 注解的值进行相应的逻辑处理.
我的框架 使用了注解的值 来 控制权限.
- 官方代码
<?php
interface ActionHandler
{
public function excute();
}
#[Attribute]
class SetUp{}
class CopyFile implements ActionHandler
{
public $fileName;
public $targetDirectory;
#[SetUp]
public function fileExists()
{
if (!file_exists($this->fileName)){
throw new RuntimeException("File does not exist");
}
}
#[SetUp]
public function excute()
{
// TODO: Implement excute() method.
copy($this->fileName,$this->targetDirectory."/".basename($this->fileName));
}
}
function excuteAction(ActionHandler $actionHandler)
{
$reflection = new ReflectionObject($actionHandler);
// var_dump($reflection);die();
// var_dump($reflection->getMethods());die();
foreach ($reflection->getMethods() as $method){
// var_dump($method);
// echo "<br>";
$attributes = $method->getAttributes(SetUp::class);
var_dump($attributes);
echo "<br>";
//die();
if (count($attributes)>0){
$methodName = $method->getName();
var_dump($methodName);
echo "<br>";
$actionHandler->$methodName();
}
}
// die();
$actionHandler->excute();
}
$copyAction = new CopyFile();
$copyAction->fileName = "./favicon.ico";
$copyAction->targetDirectory="./static/";
excuteAction($copyAction);
echo "hello".rand(1,10);