php实现注解
使用 PHP 原生反射实现注解
PHP 本身没有内置注解功能,但可以通过反射(Reflection)和文档块(DocBlock)解析实现类似注解的效果。以下是一个基础实现方法:
class Annotation {
public static function getMethodAnnotations($className, $methodName) {
$reflection = new ReflectionMethod($className, $methodName);
$docComment = $reflection->getDocComment();
return self::parseAnnotations($docComment);
}
private static function parseAnnotations($docBlock) {
preg_match_all('/@(\w+)(?:\s*(.*))?/', $docBlock, $matches, PREG_SET_ORDER);
$annotations = [];
foreach ($matches as $match) {
$annotations[$match[1]] = $match[2] ?? true;
}
return $annotations;
}
}
使用 Doctrine Annotations 库
Doctrine Annotations 是一个成熟的 PHP 注解解析库:
use Doctrine\Common\Annotations\AnnotationReader;
class MyController {
/
* @Route("/example", methods={"GET"})
*/
public function exampleAction() {
// 方法实现
}
}
$reader = new AnnotationReader();
$reflectionMethod = new ReflectionMethod('MyController', 'exampleAction');
$routeAnnotation = $reader->getMethodAnnotation($reflectionMethod, 'Route');
自定义注解类
可以创建自定义注解类:
/
* @Annotation
* @Target("METHOD")
*/
class Route {
public $path;
public $methods = [];
public function __construct(array $data) {
$this->path = $data['path'] ?? $data['value'] ?? '';
$this->methods = $data['methods'] ?? [];
}
}
注解处理器实现
处理注解并执行相应逻辑:
class AnnotationProcessor {
public function process($className) {
$reflectionClass = new ReflectionClass($className);
foreach ($reflectionClass->getMethods() as $method) {
$reader = new AnnotationReader();
$route = $reader->getMethodAnnotation($method, Route::class);
if ($route) {
$this->registerRoute($route->path, [$className, $method->getName()], $route->methods);
}
}
}
}
性能优化考虑
对于生产环境,应考虑缓存注解解析结果:
use Doctrine\Common\Annotations\CachedReader;
use Doctrine\Common\Cache\ArrayCache;
$cache = new ArrayCache();
$reader = new CachedReader(new AnnotationReader(), $cache);
现代 PHP 替代方案
PHP 8.0+ 原生支持属性(Attributes),可作为注解的替代:
#[Attribute(Attribute::TARGET_METHOD)]
class Route {
public function __construct(
public string $path,
public array $methods = []
) {}
}
class MyController {
#[Route('/example', methods: ['GET'])]
public function exampleAction() {
// 方法实现
}
}






