一. 首先说下什么是注解,
- 注解只不过就是一种注释,如没有代码解析它,那他就啥都不是,一段代码通过识别注解来做不同的事情这就是注解的意义
- 他有何作用呢。
举个例子,我要对某些方法做一个权限控制,判断这个方法有没有权限,普通做法是需要验证权限的接口调用一个方法去验证.那需要验证的方法都会有一行调用方法的代码,这不符合低偶高聚,有些同学会在类的构造方法里统一调用,根据方法名排除不需要调用的方法这也不错。但是有了java的开发经验后我并不想回到过去~~没事找事型。毕竟学一个东西就是学一种思想,学他的方式方法,所以大胆尝试,在需要判断权限的方法上加注解然后利用AOP或者拦截器来验证权限。二. 既然java能利用注解那么php也能,毕竟php是世界上最好的语言
java注解 是一个继承了Annotations的接口。
然后在方法 或字段属性上注解
- @Test public void test(){};
那么php该如何实现呢,毕竟php不能在方法前写 @Test.
你要是非要在方法前加注解那就走远了,理解其原理是个注释那就简单了。
php也能写注释呀 /***/写在方法前。 那答案就来了,如何能获取这个注释读取分析不就完了吗。
那么能不能呢~,那肯定能呀(php是世界上最好的语言),想到以前写php的时候用到的自动根据注释生成文档,他肯定是读取了注释解析注释生成的,不然就超出了我的认知范围,不可能是别的了。
于是去百度呀,嘿嘿,难不成你才想我下一步回去翻那个包的源码吗,百度下php后去注释代码,果然一堆文章凭借老道经验找到了方法。三. 然后写出了下面的方法,下面的方法就是获取注释啦。可以到php官网看
ReflectionMethod这个类的各种方法讲解有好多参数可以获取
$m = new ReflectionMethod($this, $this->request->action());
//方法注释
$annotationStr = $m->getDocComment();
$annotation = (new DocParser())->parse($annotationStr);
下面这个类是解析文档的。
params;
}
// Get the comment
if (preg_match ( '#^/\*\*(.*)\*/#s', $doc, $comment ) === false)
return $this->params;
$comment = trim ( $comment [1] );
// Get all the lines and strip the * from the first character
if (preg_match_all ( '#^\s*\*(.*)#m', $comment, $lines ) === false)
return $this->params;
$this->parseLines ( $lines [1] );
return $this->params;
}private function parseLines($lines) {
$desc = [];
foreach ( $lines as $line ) {
$parsedLine = $this->parseLine ( $line );
// Parse the lineif ($parsedLine === false && ! isset ( $this->params ['description'] )) {
if (isset ( $desc )) {
// Store the first line in the short description
$this->params ['description'] = implode ( PHP_EOL, $desc );
}
$desc = array ();
} elseif ($parsedLine !== false) {
$desc [] = $parsedLine;
// Store the line in the long description
}
}
$desc = implode ( ' ', $desc );
if (! empty ( $desc ))
$this->params ['long_description'] = $desc;
}private function parseLine($line) {
// trim the whitespace from the line
$line = trim ( $line );
if (empty ( $line ))
return false;
// Empty lineif (strpos ( $line, '@' ) === 0) {
if (strpos ( $line, ' ' ) > 0) {
// Get the parameter name
$param = substr ( $line, 1, strpos ( $line, ' ' ) - 1 );
$value = https://www.it610.com/article/substr ( $line, strlen ( $param ) + 2 );
// Get the value
} else {
$param = substr ( $line, 1 );
$value ='';
}
// Parse the line and return false if the parameter is valid
if ($this->setParam ( $param, $value ))
return false;
}return $line;
}private function setParam($param, $value) {
if ($param == 'param' || $param == 'header')
$value = https://www.it610.com/article/$this->formatParam( $value );
if ($param == 'class')
list ( $param, $value ) = $this->formatClass ( $value );
if($param == 'return' || $param == 'param' || $param == 'header'){
$this->params [$param][] = $value;
}else if (empty ( $this->params [$param] )) {
$this->params [$param] = $value;
} else {
$this->params [$param] = $this->params [$param] . $value;
}
return true;
}private function formatClass($value) {
$r = preg_split ( "[\(|\)]", $value );
if (is_array ( $r )) {
$param = $r [0];
parse_str ( $r [1], $value );
foreach ( $value as $key => $val ) {
$val = explode ( ',', $val );
if (count ( $val ) > 1)
$value [$key] = $val;
}
} else {
$param = 'Unknown';
}
return array (
$param,
$value
);
}private function formatParam($string) {
$string = $string." ";
if(preg_match_all('/(\w+):(.*?)[\s\n]/s', $string, $meatchs)){
$param = [];
foreach ($meatchs[1] as $key=>$value){
$param[$meatchs[1][$key]] = $this->getParamType($meatchs[2][$key]);
}
return $param;
}else{
return ''.$string;
}
}private function getParamType($type){
$typeMaps = [
'string' => '字符串',
'int' => '整型',
'float' => '浮点型',
'boolean' => '布尔型',
'date' => '日期',
'array' => '数组',
'fixed' => '固定值',
'enum' => '枚举类型',
'object' => '对象',
];
return array_key_exists($type,$typeMaps) ? $typeMaps[$type] : $type;
}
}
四. 实现图
controller 层注释,看我们在注释里加了一个@PermissionAuth true五. 哈哈偷了weiwei/api-doc的代码, 所以我还是研究了那个文档的源码
文章图片
让我们的注解生效, 看断电截图我们的$annotationStr获取了注释之后,通过parse方法整理得到一个数组有我们刚在方法上定义的注解和值,此时有值并且为true需要验证权限
文章图片
> 看了他这个源码之后我们简略的把代码优化一下,直接利用weiwei/api-doc 包里面的方法得到注解完成后续操作。
![image](http://www.ichasem.tech/wp-content/uploads/2019/12/注解3.png)
六. 后续怎么利用AOP或拦截器的方法我们在单开一文详解
七. 注解不仅仅可以用作权限,还可以验证登录等等…
【php注解实现自动验证权限,php无所不能】原文更详尽链接 www.ichasem.tech
推荐阅读
- 对GO切片的理解
- 小程序商城网站开发秒杀模块篇
- 盲盒购物网站系统开发建设 第三篇
- Netty核心概念之ChannelHandler&Pipeline&ChannelHandlerContext
- 简单的线程池实现多线程对大文件的读取
- SSH 端口转发与 SOCKS 代理
- Ubuntu16.04/Scala2.11.8安装教程
- 学习PHP中的高精度计时器HRTime扩展
- 使用OpenResty+Lua实现灰度测试(金丝雀)
- 使用源码编译安装PHP扩展