php 注解实现
PHP 注解实现方法
PHP 注解(Attributes)是 PHP 8.0 引入的功能,用于为类、方法、属性等添加元数据。注解通过反射 API 读取,常用于框架、库或代码生成工具。
定义注解
注解是一个普通的 PHP 类,需用 #[Attribute] 标记。注解类可以包含构造函数和属性。
#[Attribute]
class Route {
public function __construct(
public string $path,
public string $method = 'GET'
) {}
}
使用注解
注解可以直接应用于类、方法、属性或函数参数。
#[Route(path: '/user', method: 'GET')]
class UserController {
#[Route(path: '/list', method: 'GET')]
public function list(): array {
return [];
}
}
读取注解
通过反射 API 读取注解信息。例如获取类的注解:
$reflectionClass = new ReflectionClass(UserController::class);
$attributes = $reflectionClass->getAttributes(Route::class);
foreach ($attributes as $attribute) {
$route = $attribute->newInstance();
echo $route->path; // 输出 '/user'
}
注解目标限制
可以限制注解的应用目标,例如仅允许用于方法:
#[Attribute(Attribute::TARGET_METHOD)]
class MethodOnly {}
注解参数验证
注解类的构造函数可以包含参数验证逻辑:
#[Attribute]
class Validate {
public function __construct(public string $type) {
if (!in_array($type, ['email', 'url'])) {
throw new InvalidArgumentException('Invalid validation type');
}
}
}
重复注解
PHP 8.1 开始支持重复注解:
#[Attribute(Attribute::IS_REPEATABLE)]
class Middleware {
public function __construct(public string $name) {}
}
#[Middleware('auth')]
#[Middleware('admin')]
class AdminController {}
注解继承
默认情况下子类不会继承父类的注解,除非显式指定:
$reflection = new ReflectionClass(ChildClass::class);
$attributes = $reflection->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF);
注解缓存
为提高性能,可以考虑缓存反射结果:
$cacheKey = 'annotations_'.md5(UserController::class);
if (!$cache->has($cacheKey)) {
$reflection = new ReflectionClass(UserController::class);
$annotations = extractAnnotations($reflection);
$cache->set($cacheKey, $annotations);
}
框架集成示例
在框架中常用注解实现路由:
$controllers = findClassesInPath('app/Controllers');
foreach ($controllers as $controller) {
$reflection = new ReflectionClass($controller);
$routes = $reflection->getAttributes(Route::class);
foreach ($routes as $route) {
$instance = $route->newInstance();
$router->addRoute($instance->method, $instance->path, $controller);
}
}
注解与文档块比较
相比传统的 PHPDoc 注释,注解具有更强类型检查和运行时验证:
// 传统 PHPDoc
/
* @Route("/user", method="GET")
*/
class UserController {}
// PHP 8+ 注解
#[Route(path: '/user', method: 'GET')]
class UserController {}
性能考虑
大量使用注解可能影响性能,建议:

- 缓存解析结果
- 避免在热路径中频繁反射
- 考虑预编译注解信息
常见应用场景
- 路由定义
- 依赖注入
- 数据验证
- 权限控制
- 缓存配置
- 数据库映射
注解库推荐
- Doctrine Annotations(兼容 PHP 8 前版本)
- Symfony 的注解组件
- Laravel 的注解路由
以上方法展示了 PHP 注解的核心用法和实际应用方式,可根据具体需求选择适合的实现方案。






