bennetgallein/annotations

主要用于路由声明的注解

v1.0.0 2024-04-09 16:36 UTC

README

本项目为PHP提供类似Java风格的注解。

示例

假设我们正在编写一个网络请求路由器。我们可以使用注解来提供路由以及与之关联的方法。

定义注解

<?php

require_once('Annotate.php');

/**
 * @AnnotationTarget(AnnotatedElementType::METHOD)
 */
class Route extends Annotation {}

使用上面的注解,我们现在可以定义一个控制器并应用注解。

<?php

require_once('Annotate.php');

class Controller {
	/**
	 * @Route('/')
	 */
	function home() {}
	
	/**
	 * @Route('/login')
	 */
	function login() {}
}

使用注解

现在我们已经定义了注解并将其应用于我们的控制器,我们可以定义我们的网络请求路由器。

<?php

require_once('Annotate.php');

class RequestRouter {
	function process($path) {
		$reflect = new AnnotatedReflectionClass('Controller');
        $obj = $reflect->newInstance();
        foreach ($reflect->getMethods() as $method) {
            $route = $method->getAnnotation('Route');
            if ($route->value() == $path) {
                $method->invoke($obj);
                break;
            }
        }
	}
}

这显然是我们RequestRouter的一个简单示例,但它展示了如何使用@Route注解。

具有多个值的注解

默认情况下,所有注解都有一个名为value的单个值。注解还允许您定义自己的值,如果单个值不够用。

<?php

require_once('Annotate.php');

/**
 * @AnnotationTarget(AnnotatedElementType::METHOD)
 */
class Route extends Annotation {
	public $path;
	public $method;
	
	public function __construct($path = null, $method = null) {
        $this->path = $path;
        $this->method = $method;
    }

    public function path() {
        return $this->path;
    }

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

现在我们的@Route将允许我们指定一个路径以及一个请求方法。

<?php

require_once('Annotate.php');

class Controller {
	/**
	 * @Route('/', 'GET')
	 */
	function home() {}
	
	/**
	 * @Route('/login', 'GET')
	 */
	function login() {}
	
	/**
	 * @Route('/login/auth', 'POST')
	 */
	function loginAuth() {}
}

现在我们的homelogin控制器方法表示它们支持GET请求方法,而loginAuth支持POST。我们显然需要相应地更新我们的RequestRouter

命名参数

如果您提供了注解期望的所有参数,或者您提供的所有参数都是正确的顺序,您不需要做任何特殊的事情。但是,如果您只想传递一些参数,则需要使用命名参数。

<?php

require_once('Annotate.php');

class Controller {
	/**
	 * This route ignores the method parameter
	 * @Route('/foo')
	 */
	function home() {}
	
	/**
	 * This route ignores the path parameter so we have to specify that the
	 * parameter we are passing is meant to be used as the method value.
	 * This is obviously pointless, but for the sake of example...
	 * @Route(method='GET')
	 */
	function bar() {}
}

API文档

AnnotatedReflectionClass

此类扩展ReflectionClass并引入了以下方法

  • getAnnotations
  • getAnnotation($annotationClass)
  • hasAnnotation($annotationClass)

AnnotatedReflectionMethod

此类扩展ReflectionMethod并引入了以下方法

  • getAnnotations
  • getAnnotation($annotationClass)
  • hasAnnotation($annotationClass)

AnnotatedReflectionProperty

此类扩展ReflectionProperty并引入了以下方法

  • getAnnotations
  • getAnnotation($annotationClass)
  • hasAnnotation($annotationClass)

Annotation

每次您定义自己的自定义注解时,都必须扩展此类。

@AnnotationTarget

此提供的注解用于指定注解的目标。它的value是来自AnnotatedElementType的一个值。

AnnotatedElementType

您可以为注解类指定目标并限制它们相关联的元素类型。@AnnotationTarget的值是以下这些值之一

  • ANNOTATION_TYPE - 注解类型声明
  • CONSTRUCTOR - 构造函数声明
  • METHOD - 方法声明
  • PROPERTY - 属性声明(包括常量)
  • TYPE - 类(包括注解类型),或接口声明