geeks4change/composable-inheritance
Composer 安装命令:
composer require geeks4change/composable-inheritance
包简介
Provides composable inheritance via a magic classloader.
README 文档
README
The problem
Augmenting services by decorating them is a well established practice. There is a big set of classes though, that is simple to extend but paractically impossible to decorate. Take classes with protected methods, and/or tight self-coupling (methods heavily call other methods or use protected/private state), augmenting one method typically leads to essentially copy-pasting lots of other methods, or duplicating internal state, essentially defeating the initial idea of code reuse.
We can subclass such classes, but this is not composable: In a component oriented architecture, there is no way that component A and component B can both subclass a service class without knowing thus tightly coupling each other.
An example use case
Given (like in DreamHooks) you want to augment Drupal's ModuleHandler via overriding ModuleHandler::buildImplementationInfo. It's protected anyway. But even if it were public, in a decorator we'd have to duplicate all calling methods.
So OK, we can subclass it and swap the implementation via symfony service decoration. But this is fragile (not composable): If another module does the same, only one can win.
The solution
Composable Inheritance solves this by creating extension classes at runtime, in a way that multiple extensions can subclass the same service class without needing any coupling between them.
How to use
For the above example, we Drupal's ServiceProvider mechanism to alter the container like this:
use Drupal\dreamhooks\LegacyBridge\ModuleHandlerExtensionTrait'; use Drupal\dreamhooks\LegacyBridge\ModuleHandlerExtensionInterface'; use geeks4change\composable_inheritance\ComposableInheritance; class DreamhooksServiceProvider extends ServiceProviderBase { public function alter(ContainerBuilder $container) { $definition = $container->getDefinition('module_handler'); $class = $definition->getClass(); // Or alternatively use ComposableInheritance::alter($class). $newClass = ComposableInheritance::create($class) ->useTrait(ModuleHandlerExtensionTrait::class) ->implementsInterface(ModuleHandlerExtensionInterface::class) ->class(); $definition->setClass($newClass); } } The magic class name then will at runtime be resolved to a class that extends (subclasses) the base class (whatever its name) with the trait \Drupal\dreamhooks\LegacyBridge\ModuleHandlerExtensionTrait, and additionally implements the interface \Drupal\dreamhooks\LegacyBridge\ModuleHandlerExtensionInterface.
In plain Symfony, you can use a suitable Compiler Pass.
Opcache
If you want Opcache support for the dynamically generated classes, set an environment variable named COMPOSABLE_INHERITANCE_CLASS_STORAGE_DIRECTORY to an empty directory outside your webroot (so not to open an uploaded-file remote code execution attack vector).
Caveats
Of course composing extensions or decorations can break if the logic does not play well with each other, and may or may not be fixable via priority-ordering.
Composable Inheritance can only make subclass extension composition possible in general.
geeks4change/composable-inheritance 适用场景与选型建议
geeks4change/composable-inheritance 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 2.86k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 01 月 04 日, 在 PHP 生态内属于活跃度较高的组件。
我们在过去多个企业项目中使用过 geeks4change/composable-inheritance 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 geeks4change/composable-inheritance 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
统计信息
- 总下载量: 2.86k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 26
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: Apache-2.0
- 更新时间: 2026-01-04