如何高效获取PHP属性简洁读取API扩展包信息?

摘要:推荐 PHP 属性(Attributes) 简洁读取 API 扩展包 PHP 8.0 引入的 Attributes(属性)为类、方法、属性、常量和参数添加结构化元数据提供了便利方式。尽管概念设计合理,但读取这些属性所需的反射 API 却显得
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包 PHP 8.0 引入的 Attributes(属性)为类、方法、属性、常量和参数添加结构化元数据提供了便利方式。尽管概念设计合理,但读取这些属性所需的反射 API 却显得过于冗长。原本简单的一行操作,往往要写成多行样板代码。若需在某个类中查找某属性的全部使用位置,还得编写层层嵌套的循环。 Spatie 近期发布的 php-attribute-reader 包提供了一套干净的静态 API,专门解决上述问题。 使用 Attribute Reader 假设有一个携带 Route 属性的控制器,目标是获取该属性的实例。使用原生 PHP 反射的写法如下: $reflection = new ReflectionClass(MyController::class); $attributes = $reflection->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF); $route = null; if (count($attributes) > 0) { $route = $attributes[0]->newInstance(); } 这段代码长达五行,且仍需处理属性不存在的情况。使用 php-attribute-reader 后简化为: use Spatie\Attributes\Attributes; $route = Attributes::get(MyController::class, Route::class); 单行完成。属性不存在时返回 null,无需额外的异常处理。 读取方法属性 从方法读取属性时,原生反射的繁琐程度进一步加剧。以下示例试图获取控制器 index 方法的 Route 属性: $reflection = new ReflectionMethod(MyController::class, 'index'); $attributes = $reflection->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF); $route = null; if (count($attributes) > 0) { $route = $attributes[0]->newInstance(); } 样板代码重复出现,仅反射类有所不同。该包通过专用方法统一处理各类目标: Attributes::onMethod(MyController::class, 'index', Route::class); Attributes::onProperty(User::class, 'email', Column::class); Attributes::onConstant(Status::class, 'ACTIVE', Label::class); Attributes::onParameter(MyController::class, 'show', 'id', FromRoute::class); 全类扫描 原生反射在整类范围内查找属性时最为繁琐。
阅读全文