zenstruck / class-metadata
添加人类可读的类别名和元数据,实现高效的查找。
Requires
- php: >=8.0
- composer-plugin-api: ^2.0
Requires (Dev)
- composer/composer: ^2.4
- doctrine/persistence: ^1.0|^2.0|^3.0
- phpstan/phpstan: ^1.4
- phpunit/phpunit: ^9.5
- symfony/phpunit-bridge: ^6.0
Suggests
- doctrine/persistence: To use the AliasManagerRegistry decorator
Conflicts
- composer: <2.4
README
使用高效的运行时查找,将人类可读的类别名和标量元数据添加到您的类中。这些可以通过 属性 或 composer.json 配置 添加。
- 别名:类的简短名称(可以用来在数据库中存储 FQCN 的替代方案)。
- 元数据:特定于类的标量值键值对映射(可以用来在审计系统中标记类为 可追踪)。
此库提供了一个 Composer 插件,该插件通过挂钩到 Composer 的 dump-autoload 事件来生成用于 运行时 的查找映射。
安装
注意:此包需要 composer 2.4+。
composer require zenstruck/class-metadata
- 当被问及是否启用 Composer 插件时,选择
y
(是)。
配置
可以通过 属性 或 composer.json
配置将元数据和别名添加到类中。
- 别名必须是非空字符串。
- 每个类只允许一个别名。
- 多个类不能有相同的别名。
- 元数据键必须是字符串。
- 元数据值必须是标量(
bool|float|int|string
)。
注意:在开发期间,当添加/更改/删除别名和元数据时,您需要运行
composer dump-autoload
以使更改生效。
属性
在创建应用程序的自动加载配置时,Composer 插件会扫描您的 PSR-4 autoload
路径(在您的 composer.json
中定义),以查找具有 Alias
& Metadata
属性的类。这些属性将被解析,并生成一个映射文件。
namespace App\Entity; use Zenstruck\Alias; use Zenstruck\Metadata; #[Alias('user')] #[Metadata('track', true)] #[Metadata('identifier', 'getId')] class User { // ... }
自定义路径
如果您有一个大型代码库,扫描所有文件可能会很耗时。您可以在 composer.json
中配置要扫描的特定路径。
{ "extra": { "class-metadata": { "paths": [ "src/Domain/*/Entity" ] } } }
您也可以完全禁用路径扫描,并通过您的 composer.json
进行配置。
{ "extra": { "class-metadata": { "paths": false } } }
composer.json
元数据和别名也可以在您的 composer.json
中配置。这允许将别名和元数据添加到第三方类中
{ "extra": { "class-metadata": { "map": { "Vendor\\Code\\Class1": "class1", "Vendor\\Code\\Class2": { "alias": "class2", "key1": "value", "key2": 7 } } } } }
对于映射,字符串是别名的快捷方式(如上面的示例中的 class1
)。数组将用作元数据,除了特殊的 alias
键之外。此值将用作 别名(如上面的示例中的 class2
)。
运行时 API
由于别名/元数据映射是在 Composer 创建自动加载文件时创建的,因此运行时查找很快 - 只需从生成的 PHP 常量 数组中获取。
以下示例使用上述 用户类。
别名查找
use Zenstruck\Alias; // alias for class lookup: Alias::for(User::class); // "user" (string|null - the alias for User or null if none) Alias::for(new User()); // "user" (alternatively, you can pass the object directly) // class for alias lookup: Alias::classFor('user'); // "App\Entity\User" (class-string|null - the FQCN whose alias is "user")
元数据查找
use Zenstruck\Metadata; // metadata for a class Metadata::for(User::class); // ['track' => true, 'identifier' => 'getId'] (array<string,scalar> - metadata array for User or empty array if none) Metadata::for(new User()); // ['track' => true, 'identifier' => 'getId'] (alternatively, you can pass the object directly) Metadata::for('user'); // ['track' => true, 'identifier' => 'getId'] (alternatively, fetch metadata by a class' alias) // metadata value for key Metadata::get(User::class, 'track'); // true (scalar|null - the metadata value for "key" or null if none) Metadata::get(new User(), 'track'); // true (alternatively, you can pass the object directly) Metadata::get('user', 'track'); // true (alternatively, fetch metadata by a class' alias) // "first" metadata value for list of keys Metadata::first(User::class, 'audit_id', 'identifier', 'id'); // "getId" (scalar|null - first metadata value found for" keys" (left to right) or null if none) Metadata::first(new User(), 'audit_id', 'identifier', 'id'); // "getId" (alternatively, you can pass the object directly) Metadata::first('user', 'audit_id', 'identifier', 'id'); // "getId" (alternatively, fetch metadata by a class' alias) // all classes with metadata key Metadata::classesWith('identifier'); // ["App\Entity\User"] (class-string[] - FQCN's that have metadata with key "identifier")
list-class-metadata
命令
提供了一个自定义 Composer 命令,用于调试/列出所有已配置元数据/别名的类
composer list-class-metadata
使用上述的用户示例,以下将会输出
----------------- ------- -------------------------------------
Class Alias Metadata
----------------- ------- -------------------------------------
App\Entity\User user {"track":true,"identifier":"getId"}
----------------- ------- -------------------------------------
Doctrine 桥接器
别名管理注册器(AliasManagerRegistry)
这是一个装饰过的ManagerRegistry
,允许使用别名来调用getRepository()
和getManagerForClass()
方法
use Zenstruck\Metadata\Bridge\Doctrine\AliasManagerRegistry; /** @var \Doctrine\Persistence\ManagerRegistry $inner */ $registry = new AliasManagerRegistry($inner); $registry->getRepository('user'); // converts "user" alias to FQCN $registry->getRepository(User::class); // can still use FQCN $registry->getManagerForClass('user'); // converts "user" alias to FQCN $registry->getManagerForClass(User::class); // can still use FQCN