php 注解实现
在 PHP 中实现注解(Annotations)可以通过反射(Reflection)和文档块(DocBlock)解析来实现。以下是几种常见的实现方式:
使用 Doctrine Annotations 库
Doctrine Annotations 是一个流行的 PHP 注解库,广泛用于 Symfony 和其他框架中。
安装 Doctrine Annotations:
composer require doctrine/annotations
定义注解类:
use Doctrine\Common\Annotations\Annotation;
/
* @Annotation
* @Target("METHOD")
*/
class Route {
public $path;
public $methods = [];
}
使用注解:
use Doctrine\Common\Annotations\AnnotationReader;
class MyController {
/
* @Route(path="/users", methods={"GET"})
*/
public function listUsers() {
// ...
}
}
$reader = new AnnotationReader();
$method = new ReflectionMethod(MyController::class, 'listUsers');
$routeAnnotation = $reader->getMethodAnnotation($method, Route::class);
echo $routeAnnotation->path; // 输出 "/users"
使用 PHP 8 原生属性(Attributes)
PHP 8 引入了原生属性(Attributes),可以作为注解的现代替代方案。
定义属性类:
#[Attribute(Attribute::TARGET_METHOD)]
class Route {
public function __construct(
public string $path,
public array $methods = []
) {}
}
使用属性:
class MyController {
#[Route(path: '/users', methods: ['GET'])]
public function listUsers() {
// ...
}
}
$method = new ReflectionMethod(MyController::class, 'listUsers');
$routeAttribute = $method->getAttributes(Route::class)[0]->newInstance();
echo $routeAttribute->path; // 输出 "/users"
自定义 DocBlock 解析
如果不想依赖第三方库,可以手动解析 DocBlock 注释。
解析示例:
class MyController {
/
* @route /users
* @methods GET,POST
*/
public function listUsers() {
// ...
}
}
$method = new ReflectionMethod(MyController::class, 'listUsers');
$docComment = $method->getDocComment();
preg_match('/@route\s+(.+)/', $docComment, $routeMatches);
preg_match('/@methods\s+(.+)/', $docComment, $methodsMatches);
$route = $routeMatches[1] ?? '';
$methods = explode(',', $methodsMatches[1] ?? '');
echo $route; // 输出 "/users"
注解的常见应用场景
- 路由定义:如 Symfony 和 Laravel 中的路由注解
- 权限控制:定义方法或类需要的权限
- 数据验证:定义字段验证规则
- 依赖注入:标记需要自动注入的服务
性能考虑
- Doctrine Annotations 使用缓存机制提高性能
- PHP 8 原生属性性能优于 DocBlock 解析
- 在生产环境中应启用注解缓存
选择哪种实现方式取决于项目需求:
- 新项目推荐使用 PHP 8 原生属性
- 遗留项目或需要广泛兼容性时使用 Doctrine Annotations
- 简单需求可以考虑自定义 DocBlock 解析







