Doctrine注释提供了为PHP类实现自定义注释功能的功能(这里使用的是v1.6版本)。

composer require doctrine/annotations

官方链接:https://www.doctrine-project.org/projects/doctrine-annotations/en/1.6/index.html#introduction

使用大概步骤:

  1. 定一个注释模板文件
  2. 在类文件中使用注释(可以看做是给模板赋值)
  3. 读取注释

使用示例: https://www.cnblogs.com/cshaptx4869/p/12178960.html

# Route.php (定义一个注解模板)

<?php

namespace Util\Annotation;

use Doctrine\Common\Annotations\Annotation\Attributes;
//use Doctrine\Common\Annotations\Annotation\Enum;
//use Doctrine\Common\Annotations\Annotation\Required; /**
* 创建一个注释类
*
* Annotation表示该类是一个注解类
* Target表示注解生效的范围(ALL,CLASS,METHOD,PROPERTY,ANNOTATION)
*
* @Annotation
* @Target({"METHOD"})
* 也可以在这里变量声明类型
* @Attributes({
* @Attribute("time", type = "int")
* })
*/
final class Route
{
/**
* @Required()
* @var string
*/
public $route; /**
* @Enum({"POST", "GET", "PUT", "DELETE"})
* @var string
*/
public $method; /**
* @var array
*/
public $param; public $time; public function say()
{
echo 'hello';
}
}

# run.php (使用、读取)

<?php

require 'vendor/autoload.php';

use Util\Annotation\Route;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\FileCacheReader;
use Doctrine\Common\Annotations\AnnotationRegistry; /**
* Class UserController
* 模拟在User控制其中定义注解路由
* @author 银酱
*/
class UserController
{
/**
* 列表
* @Route(route="/user/index",method="GET")
*/
public function index()
{
echo __METHOD__;
} /**
* 注册
* @Route(route="/user/register",method="POST",param={"token","access"},time=123)
*/
public function register()
{
echo __METHOD__;
} /**
* 显示
* @Route(route="/user/info",method="POST")
*/
public function info()
{
echo __METHOD__;
} /**
* 更新
* @Route(route="/user/update",method="POST")
*/
public function update()
{ } /**
* 删除
* @Route(route="/user/info",method="DELETE")
*/
public function delete()
{
echo __METHOD__;
}
} //echo '<pre>'; // 注释使用自己的自动加载机制来确定给定的注释是否具有可以自动加载的对应PHP类
// 配置注释自动加载(2.0版本中已剔除)
AnnotationRegistry::registerLoader('class_exists'); //回调需返回true
//AnnotationRegistry::registerFile(__DIR__ . '/Util/Annotation/Route.php'); //注册文件
//AnnotationRegistry::registerAutoloadNamespace('Util\Annotation'); //注册命名空间
//AnnotationRegistry::registerAutoloadNamespaces(['Util\\Annotation' => null]); //注册多个命名空间 // 系统默认 var、author 标记不会识别
$whitelist = [
"after", "afterClass", "backupGlobals", "backupStaticAttributes", "before", "beforeClass", "codeCoverageIgnore*",
"covers", "coversDefaultClass", "coversNothing", "dataProvider", "depends", "doesNotPerformAssertions",
"expectedException", "expectedExceptionCode", "expectedExceptionMessage", "expectedExceptionMessageRegExp", "group",
"large", "medium", "preserveGlobalState", "requires", "runTestsInSeparateProcesses", "runInSeparateProcess", "small",
"test", "testdox", "testWith", "ticket", "uses"
];
foreach ($whitelist as $v) {
AnnotationReader::addGlobalIgnoredName($v);
} $reflectionClass = new \ReflectionClass(UserController::class);
$methods = $reflectionClass->getMethods(); //$reader = new AnnotationReader();
//缓存 reader, 开启debug 若有修改则会更新,否则需手动删除然后更新
$reader = new FileCacheReader(new AnnotationReader(), "runtime/annotation", true); foreach ($methods as $method) {
// 读取Route的注解
$routeAnnotation = $reader->getMethodAnnotation($method, Route::class);
echo '========================' . PHP_EOL;
echo "route: {$routeAnnotation->route}" . PHP_EOL . PHP_EOL;
echo "method: {$routeAnnotation->method}" . PHP_EOL;
$param = print_r($routeAnnotation->param, true);
echo "param: {$param}" . PHP_EOL;
$routeAnnotations[] = $routeAnnotation;
} //var_dump($routeAnnotations);

# 其余实例1

<?php
// 错误处理机制
register_shutdown_function('myShutDown');
set_error_handler('myError');
set_exception_handler('myException'); // require自动加载文件
require 'vendor/autoload.php'; // 该类是一个辅助类,几个属性$value $type $desc将用于描述其他类的属性、方法或者对象的。
/**
* @Annotation
* @Target({"ALL"})
*/
class AnnotatedDescription
{
/**
* @var mixed
*/
public $value; /**
* @var string
*/
public $type; /**
* @var string
*/
public $desc;
} /**
* @AnnotatedDescription("这是一个用于展示Annotation类的例子。")
*/
class AnnotationDemo
{
/**
* @AnnotatedDescription(desc="这个属性必须要为String",type="String")
* @var String
*/
private $property = "I am a private property!"; /**
* @AnnotatedDescription(value="啦啦")
* @var string
*/
protected $extra; /**
* @AnnotatedDescription(desc="不需要传入参数", type="getter")
*/
public function getProperty()
{
return $this->property;
}
} echo "<pre>";
// Lets parse the annotations
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\FileCacheReader; // 缓存到文件
//$annotationReader = new FileCacheReader(new AnnotationReader(), './cache/annotation', true);
$annotationReader = new AnnotationReader(); // Get class annotation
$reflectionClass = new ReflectionClass(AnnotationDemo::class);
// public function getClassAnnotations(\ReflectionClass $class); 访问类的所有注释
$classAnnotations = $annotationReader->getClassAnnotations($reflectionClass);
echo "========= CLASS ANNOTATIONS =========" . PHP_EOL;
print_r($classAnnotations); $annotationDemoObject = new AnnotationDemo();
$reflectionObject = new ReflectionObject($annotationDemoObject);
$objectAnnotations = $annotationReader->getClassAnnotations($reflectionObject);
echo "========= OBJECT ANNOTATIONS =========" . PHP_EOL;
print_r($objectAnnotations); $reflectionProperty = new ReflectionProperty(AnnotationDemo::class, 'property');
// public function getPropertyAnnotations(\ReflectionProperty $property); 访问属性的所有注释
$propertyAnnotations = $annotationReader->getPropertyAnnotations($reflectionProperty);
echo "========= PROPERTY ANNOTATIONS =========" . PHP_EOL;
print_r($propertyAnnotations); $reflectionMethod = new ReflectionMethod(AnnotationDemo::class, 'getProperty');
// public function getMethodAnnotations(\ReflectionMethod $method); 访问方法的所有注释
$methodAnnotations = $annotationReader->getMethodAnnotations($reflectionMethod);
echo "========= Method ANNOTATIONS =========" . PHP_EOL;
print_r($methodAnnotations); function myException($e)
{
var_dump('<h3 style="color:red;">myException:'.$e->getMessage().'</h3>');
} function myError($code, $msg, $file, $line)
{
var_dump(compact('code', 'msg', 'file', 'line'));
} function myShutDown()
{
$data = error_get_last();
if(is_null($data)){
var_dump('nothing error');
} else {
var_dump('error',$data);
}
}

# 其余实例2

<?php

set_exception_handler('my_exception');

require_once 'vendor/autoload.php';

use Doctrine\Common\Annotations\AnnotationReader;

/**
* 如果您想定义自己的注释,只需将它们分组到一个名称空间中,并在AnnotationRegistry中注册这个名称空间
* 注释类必须包含带有文本的类级docblock Annotation
* @Annotation
*
* 表明注释类型适用于的类元素的类型,即注入注释允许的范围
* 可选值 CLASS,PROPERTY,METHOD,ALL,ANNOTATION ,可选一个或者多个
* 如果在当前上下文中不允许注释,则会得到一个AnnotationException
* @Target({"METHOD","PROPERTY","CLASS"})
*
* 修饰属性
* @Attributes({
* @Attribute("func", type="string"),
* })
*/
class A
{
public $value; /**
* @var string
*/
public $name; /**
* 注释解析器使用phpdoc注释 var 或 Attributes and Attribute 的组合,检查给定的参数
* 可选值 mixed,boolean,bool,float,string,integer,array,SomeAnnotationClass,array<integer>,array<SomeAnnotationClass>
* 如果数据类型不匹配,则会得到一个AnnotationException
* @var integer
*/
public $age; /**
* @var array
*/
public $sex; public $func; /**
* 定义为字段必填,否则报AnnotationException异常
* @Required
*
* 限制可选值,出错报AnnotationException异常
* @Enum({"NORTH", "SOUTH", "EAST", "WEST"})
*/
public $option; // 如果存在构造函数存在参数,则会把组值传给这个参数;反之,如果没有构造函数,则直接将值注入到公共属性
public function __construct()
{
}
} /**
* @A("类注释")
*/
class B
{
/**
* 属性注释
* @A(name="tom",age=18,sex={"male","fmale","secret"},option="NORTH")
*/
public $param; /**
* 方法注释
* @A(func="say")
*/
public function say()
{ }
} $reflection = new ReflectionClass(B::class);
$reader = new AnnotationReader(); // 返回的是对象
$AClassAnnotation = $reader->getPropertyAnnotation($reflection->getProperty('param'), A::class);
// 返回的是对象组成的数组
//$AClassAnnotation = $reader->getPropertyAnnotations($reflection->getProperty('param')); //$AClassAnnotation = $reader->getMethodAnnotation($reflection->getMethod('say'), A::class); //$AClassAnnotation = $reader->getClassAnnotation($reflection, A::class); dump($AClassAnnotation); function my_exception($exception)
{
echo '<div class="alert alert-danger">';
echo '<b>Fatal error</b>: Uncaught exception \'' . get_class($exception) . '\' with message ';
echo $exception->getMessage() . '<br>';
echo 'Stack trace:<pre>' . $exception->getTraceAsString() . '</pre>';
echo 'thrown in <b>' . $exception->getFile() . '</b> on line <b>' . $exception->getLine() . '</b><br>';
echo '</div>';
exit();
} function dump($data)
{
echo '<pre>';
var_dump($data);
exit();
}

# 其他事项:

// 注释使用自己的自动加载机制来确定给定的注释是否具有可以自动加载的对应PHP类
// 配置注释自动加载3种方式(2.0中已删除)
AnnotationRegistry::registerLoader('class_exists'); //回调需返回true

//AnnotationRegistry::registerFile(__DIR__ . '/Util/Annotation/Route.php'); //注册文件
//AnnotationRegistry::registerAutoloadNamespace('Util\Annotation'); //注册命名空间

//AnnotationRegistry::registerAutoloadNamespaces(['Util\\Annotation' => null]); //注册多个命名空间

// 添加标签白名单 系统默认去除author 和 var
$whitelist = ["author", "after", "afterClass", "backupGlobals", "backupStaticAttributes", "before", "beforeClass", "codeCoverageIgnore*", "covers", "coversDefaultClass", "coversNothing", "dataProvider", "depends", "doesNotPerformAssertions", "expectedException", "expectedExceptionCode", "expectedExceptionMessage", "expectedExceptionMessageRegExp", "group", "large", "medium", "preserveGlobalState", "requires", "runTestsInSeparateProcesses", "runInSeparateProcess", "small", "test", "testdox", "testWith", "ticket", "uses"];
foreach ($whitelist as $v) {
AnnotationReader::addGlobalIgnoredName($v);
}

# API:

Access all annotations of a class

public function getClassAnnotations(\ReflectionClass $class);

Access one annotation of a class

public function getClassAnnotation(\ReflectionClass $class, $annotationName);

Access all annotations of a method

public function getMethodAnnotations(\ReflectionMethod $method);

Access one annotation of a method

public function getMethodAnnotation(\ReflectionMethod $method, $annotationName);

Access all annotations of a property

public function getPropertyAnnotations(\ReflectionProperty $property);

Access one annotation of a property

public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);

doctrine/annotation 的简单使用的更多相关文章

  1. 菜鸟学习Spring——60s使用annotation实现简单AOP

    一.概述. AOP大家都知道切面编程,在Spring中annotation可以实现简单的AOP列子.下面还未大家介绍几个概念: Aspect 对横切性关注点的模块化. Advice 对横切性关注点的具 ...

  2. Spring基于 Annotation 的简单介绍

    tyle="margin:20px 0px 0px; font-size:14px; line-height:26px; font-family:Arial"> 1.使用 @ ...

  3. annotation注释简单介绍

    元数据的作用 如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类: l         编写文档:通过代码里标识的元数据生成文档. l         ...

  4. 菜鸟学习Spring——60s配置XML方法实现简单AOP

    一.概述. 上一篇博客讲述了用注解的形式实现AOP现在讲述另外一种AOP实现的方式利用XML来实现AOP. 二.代码演示. 准备工作参照上一篇博客<菜鸟学习Spring--60s使用annota ...

  5. Annotation(jdk5.0注解)复习(转自http://3w_cnblogs_com/pepcod/)

    package annotation.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retent ...

  6. Java Annotation手册

    Java Annotation手册 作者:cleverpig(作者的Blog:http://blog.matrix.org.cn/page/cleverpig) 原文:http://www.matri ...

  7. Annotation注解

    概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annotation就是提供了一种为程序元素设置元数据的方法,可用于修饰包.类. ...

  8. VS简单注释插件——VS插件开发续

    VS简单注释插件——VS插件开发续 前些时候,我写过一篇<VS版权信息插件——初试VS插件开发小记>分享过一个用于添加注释信息的插件,但那个插件有几个问题: 不能添加带块注释(/**/), ...

  9. Hibernate---第一个helloworld程序 (XML版本, annotation版本)

    Hibernate作为JPA的一种实现,jpa的注解已经是hibernate的核心,hibernate只提供了一些补充,而不是两套注解.hibernate对jpa的支持够足量,在使用hibernate ...

随机推荐

  1. C#4.0 HTTP协议无法使用TLS1.2的问题

    在发送HTTP请求前加入下行代码 ServicePointManager.SecurityProtocol = (SecurityProtocolType) | (SecurityProtocolTy ...

  2. 58.Less介绍及其与Sass的差异

    Less英文官网需要开启VPN才能正常访问,如果你无法打开Less官网,建议您移步到Alexis Sellier领导的团队所译的中文官网Less中文. ——大漠 事实证明,Less——以及Sass对于 ...

  3. 框架——flask知识点回顾

    1. flask--轻量级Web开发框架 2. Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL 3. Web程序框架的意义: 用于搭建Web应用程序 免去不同Web应用 ...

  4. hive 调优手段

    调优手段 ()利用列裁剪 当待查询的表字段较多时,选取需要使用的字段进行查询,避免直接select *出大表的所有字段,以免当使用Beeline查询时控制台输出缓冲区被大数据量撑爆. ()JOIN避免 ...

  5. [Android] TextView上同时显示图标和文字

    需求场景 +----------------------------+ | Icon TEXT | +----------------------------+ 当然,可以使用LineLayout,包 ...

  6. Oarcle 入门之注释与关键字

    --1.--单行注释 *输入法应定要为英文 --2./*多行注释 *与java相似*/   ------------------------------------------------------ ...

  7. java.lang.ClassCastException: com.sun.proxy.$Proxy* cannot be cast to***

    Spring AOP 有两种代理方法, 一种是常规JDK,一种是CGLIB. 当代理对象实现了至少一个接口时,默认使用JDK动态创建代理对象: 当代理对象没有实现任何接口时,就会使用CGLIB方法. ...

  8. dva构建react项目

    第一步:安装 dva-cli 1 cnpm install dva-cli -g 第二步:采用dva来创建项目: 1 dva new react_two 2 cd react_two 用webstor ...

  9. 简单代码生成csv文件(excel)

    $arr = array('');// 目标数组 header("Content-Type:application/vnd.ms-excel;charset=gbk"); head ...

  10. Vue基础进阶 之 实例方法--生命周期

    在上一篇博客中我们知道生命周期的方法: 生命周期: vm.$mount:手动挂载Vue实例: vm.$destroy:销毁Vue实例,清理数据绑定,移除事件监听: vm.$nextTick:将方法中的 ...