droath/plugin-manager
Composer 安装命令:
composer require droath/plugin-manager
包简介
A lightweight PHP package for defining, discovering and instantiating pluggable services.
README 文档
README
A lightweight PHP toolkit for discovering, describing, and instantiating pluggable services. It couples attribute-based metadata with a flexible discovery pipeline so you can publish extensions without wiring every class manually.
Features
- Attribute-first definitions: describe plugins with
#[PluginMetadata]directly on the class. - Namespace discovery: scan one or more namespaces for implementations that match your interface contract.
- Extensible managers: override the constructor of
DefaultPluginManagerto inject discovery and container wiring. - Container integration: opt into PSR-11 containers for dependency-rich plugins.
- Testing utilities: reference stubbed discovery helpers to keep specs fast and focused.
Installation
composer require droath/plugin-manager
The library targets PHP 8.1+ and expects Composer’s autoloader at runtime.
Core Concepts
- Plugin metadata attribute:
Droath\PluginManager\Attributes\PluginMetadatamarks eligible classes and captures identity fields such asidandlabel. - Plugin contracts: every plugin must implement
Droath\PluginManager\Contracts\PluginInterface. ThePlugin\PluginBaseabstract class ships with sensible defaults. - Discovery:
Discovery\NamespacePluginDiscoveryscans configured namespaces for attributed classes that implement one or more target interfaces. - Plugin manager:
DefaultPluginManagerexpects a discovery implementation via its constructor. Extend it and override__construct()to provide the discovery strategy (and optionally register a container). - Container awareness: when a plugin implements
PluginContainerInjectionInterfacethe manager must satisfyPluginManagerContainerAwareInterface(seeConcerns\ContainerAware).
Quick Start
1. Declare a plugin
<?php namespace App\Acme\Plugin; use Droath\PluginManager\Attributes\PluginMetadata; use Droath\PluginManager\Plugin\PluginBase; #[PluginMetadata(id: 'hello_world', label: 'Hello World')] final class HelloWorldPlugin extends PluginBase { public function greet(): string { $name = $this->getConfiguration()['name'] ?? 'World'; return sprintf('Hello %s!', $name); } }
2. Create a manager by overriding __construct()
<?php namespace App\Acme\Plugin; use Droath\PluginManager\Attributes\PluginMetadata; use Droath\PluginManager\Concerns\ContainerAware; use Droath\PluginManager\Contracts\PluginInterface; use Droath\PluginManager\Contracts\PluginManagerContainerAwareInterface; use Droath\PluginManager\Contracts\PluginDiscoveryInterface; use Droath\PluginManager\DefaultPluginManager; use Droath\PluginManager\Discovery\NamespacePluginDiscovery; use Illuminate\Container\Container; // Replace with your PSR-11 container implementation final class HelloPluginManager extends DefaultPluginManager implements PluginManagerContainerAwareInterface { use ContainerAware; public function __construct(?PluginDiscoveryInterface $discovery = null) { $this->setContainer(Container::getInstance()); parent::__construct($discovery ?? new NamespacePluginDiscovery( namespaces: ['App\Acme\Plugin'], pluginInterface: PluginInterface::class, pluginMetadataAttribute: PluginMetadata::class, )); } }
Overriding the constructor lets you keep one canonical discovery definition while still injecting alternative discovery implementations (e.g., stubs) for tests.
3. Instantiate plugins
$manager = new HelloPluginManager(); $plugin = $manager->createInstance('hello_world', [ 'name' => 'Developers', ]); echo $plugin->greet(); // "Hello Developers!"
createInstance() fetches the definition from cached discovery results, merges any runtime configuration, and returns a fully constructed plugin object.
Container-Aware Plugins
When a plugin needs services from your PSR-11 container, implement PluginContainerInjectionInterface and let the manager supply the container.
<?php namespace App\Acme\Plugin; use Droath\PluginManager\Contracts\PluginContainerInjectionInterface; use Droath\PluginManager\Plugin\PluginBase; use Psr\Container\ContainerInterface; final class ContainerBackedPlugin extends PluginBase implements PluginContainerInjectionInterface { public function __construct( array $configuration, array $pluginDefinition, ) { parent::__construct($configuration, $pluginDefinition); } public static function create( ContainerInterface $container, array $configuration, array $pluginDefinition, ): static { return new static($configuration, $pluginDefinition, $container->get('service_id'); } }
Because HelloPluginManager implements PluginManagerContainerAwareInterface and calls setContainer() in its constructor, container-aware plugins receive the PSR-11 container automatically. If a plugin requests a container but the manager is not container-aware, PluginManagerRuntimeException is thrown.
Definition Caching
DefaultPluginManager caches discovery results within the lifecycle of the manager. Use these helpers when definitions change at runtime:
disableCache()— bypass the cache on the next lookup (useful when discovery inputs change).resetCache()— clear the cache while keeping caching enabled (helps after deployments or configuration changes).
Both methods return the manager instance for fluent chaining.
Testing Helpers
Leverage an in-memory discovery implementation during testing so you can bypass namespace scans:
use Droath\PluginManager\Contracts\PluginDiscoveryInterface; use Droath\PluginManager\Discovery\PluginMetadata; use Droath\PluginManager\Tests\Stubs\ArrayDiscovery; use App\Acme\Plugin\HelloPluginManager; use App\Acme\Plugin\HelloWorldPlugin; $discovery = new ArrayDiscovery([ PluginMetadata::make(HelloWorldPlugin::class, [ 'id' => 'hello_world', 'label' => 'Hello World Plugin', ]), ]); $manager = new HelloPluginManager($discovery);
The repository’s specs under tests/Unit show additional examples covering discovery filters, caching, and container-aware plugins.
Development
- Static analysis:
composer analyze - Run the test suite:
composer test - Check coding standards:
vendor/bin/phpcs --standard=phpcs.xml src
droath/plugin-manager 适用场景与选型建议
droath/plugin-manager 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.05k 次下载、GitHub Stars 达 0, 最近一次更新时间为 2025 年 02 月 26 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 droath/plugin-manager 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 droath/plugin-manager 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 1.05k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 9
- 依赖项目数: 1
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-02-26