php 注解实现
PHP 注解实现方法
PHP 注解(Annotations)是一种在代码中添加元数据的方式,通常用于框架、库或自定义逻辑中。PHP 本身不原生支持注解,但可以通过反射和文档块(DocBlock)实现类似功能。
使用 Doctrine Annotations 库
Doctrine Annotations 是一个流行的 PHP 注解库,可以方便地解析和使用注解。
安装 Doctrine Annotations:
composer require doctrine/annotations
定义一个注解类:
use Doctrine\Common\Annotations\Annotation;
/
* @Annotation
* @Target("CLASS")
*/
class CustomAnnotation
{
public $value;
}
使用注解:
/
* @CustomAnnotation("Example Value")
*/
class AnnotatedClass
{
// 类实现
}
解析注解:
use Doctrine\Common\Annotations\AnnotationReader;
$reader = new AnnotationReader();
$reflectionClass = new ReflectionClass('AnnotatedClass');
$annotation = $reader->getClassAnnotation($reflectionClass, CustomAnnotation::class);
echo $annotation->value; // 输出 "Example Value"
使用 PHP 原生反射和文档块
如果不使用第三方库,可以通过 PHP 的反射和正则表达式解析文档块来实现简单注解。
定义文档块注解:
/
* @Route("/path", methods={"GET"})
*/
class MyController
{
// 类实现
}
解析文档块:
$reflectionClass = new ReflectionClass('MyController');
$docComment = $reflectionClass->getDocComment();
preg_match('/@Route\("([^"]+)", methods={([^}]+)}\)/', $docComment, $matches);
$path = $matches[1];
$methods = json_decode(str_replace("'", '"', $matches[2]), true);
echo $path; // 输出 "/path"
print_r($methods); // 输出 ["GET"]
使用 PHP 8 原生属性
PHP 8 引入了原生属性(Attributes),可以替代传统的文档块注解。
定义属性:
#[Attribute]
class Route
{
public function __construct(public string $path, public array $methods) {}
}
使用属性:
#[Route(path: "/path", methods: ["GET"])]
class MyController
{
// 类实现
}
解析属性:
$reflectionClass = new ReflectionClass('MyController');
$attributes = $reflectionClass->getAttributes(Route::class);
foreach ($attributes as $attribute) {
$route = $attribute->newInstance();
echo $route->path; // 输出 "/path"
print_r($route->methods); // 输出 ["GET"]
}
自定义注解处理器
可以结合反射和缓存机制构建自定义注解处理器,提高性能。
定义注解处理器:
class AnnotationProcessor
{
private $cache = [];
public function parse($className)
{
if (isset($this->cache[$className])) {
return $this->cache[$className];
}
$reflectionClass = new ReflectionClass($className);
$docComment = $reflectionClass->getDocComment();
$annotations = [];
// 解析逻辑
preg_match_all('/@(\w+)\(([^)]+)\)/', $docComment, $matches);
foreach ($matches[1] as $i => $name) {
$annotations[$name] = json_decode($matches[2][$i], true);
}
$this->cache[$className] = $annotations;
return $annotations;
}
}
使用处理器:
$processor = new AnnotationProcessor();
$annotations = $processor->parse('MyController');
print_r($annotations);
以上方法提供了从简单到复杂的 PHP 注解实现方案,可以根据项目需求选择合适的方式。PHP 8 的原生属性是最推荐的方式,具有更好的性能和类型安全。







