olvlvl / composer-attribute-collector
一种方便且几乎零成本的PHP 8属性目标检索方法
Requires
- php: >=8.0
- composer-plugin-api: ^2.0
Requires (Dev)
- composer/composer: >=2.4
- phpstan/phpstan: ^1.9
- phpunit/phpunit: ^9.5
README
composer-attribute-collector 是一个用于 Composer 的插件。它的目标是提供一个方便且成本极低的方式来检索PHP 8属性的的目标。在自动加载器导出后,插件会收集属性目标并生成一个静态文件。之后,可以通过方便的接口检索这些目标,而无需使用反射。当您需要在一个代码库中 发现 属性目标时,该插件非常有用——对于已知的目标,您可以使用反射。
特性
- 配置简单
- 生成的文件中无反射
- 对性能无影响
- 无依赖(当然除了Composer)
- 一个接口用于获取属性目标:类、方法和属性
- 可以将发现缓存以加快连续运行
使用方法
以下示例演示了如何检索目标和它们的属性
<?php use olvlvl\ComposerAttributeCollector\Attributes; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Routing\Annotation\Route; use Doctrine\ORM\Mapping\Column; require_once 'vendor/autoload.php'; require_once 'vendor/attributes.php'; // <-- the file created by the plugin // Find the target classes of the AsMessageHandler attribute. foreach (Attributes::findTargetClasses(AsMessageHandler::class) as $target) { // $target->attribute is an instance of the specified attribute // with the actual data. var_dump($target->attribute, $target->name); } // Find the target methods of the Route attribute. foreach (Attributes::findTargetMethods(Route::class) as $target) { var_dump($target->attribute, $target->class, $target->name); } // Find the target properties of the Column attribute. foreach (Attributes::findTargetProperties(Column::class) as $target) { var_dump($target->attribute, $target->class, $target->name); } // Filter target methods using a predicate. // You can also filter target classes and properties. $predicate = fn($attribute) => is_a($attribute, Route::class, true); # or $predicate = Attributes::predicateForAttributeInstanceOf(Route::class); foreach (Attributes::filterTargetMethods($predicate) as $target) { var_dump($target->attribute, $target->class, $target->name); } // Find class, method, and property attributes for the ArticleController class. $attributes = Attributes::forClass(ArticleController::class); var_dump($attributes->classAttributes); var_dump($attributes->methodsAttributes); var_dump($attributes->propertyAttributes);
入门
安装
composer require olvlvl/composer-attribute-collector
该插件目前处于实验阶段,其接口可能会更改。目前,它只支持类、方法和属性目标。如果您对塑造其未来感兴趣,请 贡献。
示例配置
插件仅检查配置中指定方向为 include
的路径和文件。这通常是您的 "src" 目录。将此部分添加到您的 composer.json
文件中,以在自动加载导出时生成属性文件。
有关更多信息,请参阅 配置选项。
{ "extra": { "composer-attribute-collector": { "include": [ "src" ] } } }
自动加载
您可以使用 require_once 'vendor/attributes.php';
来要求属性文件,但您可能更愿意使用Composer的自动加载功能
{ "autoloading": { "files": [ "vendor/attributes.php" ] } }
配置
包含路径或文件(仅限根目录)
使用 include
属性定义要检查属性的路径或文件。如果没有此属性,属性文件将为空。
指定的路径相对于 composer.json
文件,并且 {vendor}
占位符将替换为供应商文件夹的路径。
{ "extra": { "composer-attribute-collector": { "include": [ "path-or-file/to/include" ] } } }
排除路径或文件(仅限根目录)
使用 exclude
属性排除要检查的路径或文件。当文件引起问题或产生副作用时,这非常有用。
指定的路径相对于 composer.json
文件,并且 {vendor}
占位符将替换为供应商文件夹的路径。
{ "extra": { "composer-attribute-collector": { "exclude": [ "path-or-file/to/exclude" ] } } }
在运行之间缓存发现
插件能够维护一个缓存,以便在运行之间重用发现。要启用缓存,将环境变量 COMPOSER_ATTRIBUTE_COLLECTOR_USE_CACHE
设置为 1
、yes
或 true
。缓存项持久化在 .composer-attribute-collector
目录中,您可能希望将其添加到您的 .gitignore
文件。
使用Symfony Demo进行测试
您可以使用对 Symfony Demo应用程序 的全新安装尝试该插件。
将 composer-attribute-collector
节点添加到 extra
,并将自动加载项添加到 composer.json
文件
{ "autoload": { "files": [ "vendor/attributes.php" ] }, "extra": { "composer-attribute-collector": { "include": [ "src" ] } } }
使用Composer安装插件。系统会询问您是否信任该插件并希望激活它。如果您想继续,请选择y
。
composer require olvlvl/composer-attribute-collector
您应该会看到类似以下日志信息
Generating autoload files
Generating attributes file
Generated attributes file in 9.137 ms
Generated autoload files
插件应该已生成文件vendor/attributes.php
。让我们看看是否可以获取被标记为路由的控制器方法。创建一个包含以下内容的PHP文件并运行它
<?php use olvlvl\ComposerAttributeCollector\Attributes; use Symfony\Component\Routing\Annotation\Route; require_once 'vendor/autoload.php'; $predicate = Attributes::predicateForAttributeInstanceOf(Route::class); $targets = Attributes::filterTargetMethods($predicate); foreach ($targets as $target) { echo "action: $target->class#$target->name, path: {$target->attribute->getPath()}\n"; }
您应该会看到以下摘录的输出
action: App\Controller\BlogController#index, path: /
action: App\Controller\BlogController#index, path: /rss.xml
action: App\Controller\BlogController#index, path: /page/{page<[1-9]\d{0,8}>}
action: App\Controller\BlogController#postShow, path: /posts/{slug}
action: App\Controller\BlogController#commentNew, path: /comment/{postSlug}/new
action: App\Controller\BlogController#search, path: /search
配置了插件的演示应用程序可在GitHub上找到。
常见问题解答
我需要生成优化的自动加载器吗?
您不需要生成优化的自动加载器才能使它工作。此插件使用与Composer类似的代码来查找类。任何与Composer兼容的内容都应与插件兼容。
我可以在开发期间使用此插件吗?
是的,您可以在开发期间使用此插件,但请注意,只有在自动加载器导出之后才会生成属性文件。如果您修改了属性,您需要运行composer dump
来刷新属性文件。
作为解决方案,您可以在包含属性的类所在的目录上设置监视器,在您进行更改时运行XDEBUG_MODE=off composer dump
。PhpStorm提供文件监视器。您还可以使用spatie/file-system-watcher,它只需要PHP。如果插件运行速度不符合您的喜好,尝试使用COMPOSER_ATTRIBUTE_COLLECTOR_USE_CACHE=yes
运行命令,这将启用缓存并加快连续运行的速度。
持续集成
项目通过GitHub actions进行持续测试。
行为准则
本项目遵循贡献者行为准则。通过参与本项目及其社区,您应遵守此准则。
贡献
请参阅CONTRIBUTING以获取详细信息。
许可协议
olvlvl/composer-attribute-collector在BSD-3-Clause许可下发布。