cresset/module-fused-interceptors
Composer 安装命令:
composer require cresset/module-fused-interceptors
包简介
Replaces Magento's dynamic interceptors with fused (inlined-chain) interceptors generated at setup:di:compile time.
README 文档
README
Replaces Magento's dynamic interceptor with a fused one at setup:di:compile
time. Instead of per-call PluginList::getNext() + the ___callPlugins closure, each
plugged method inlines its resolved plugin chain as straight-line PHP, with scope
branching baked in. On a representative catalog store this removed ~30% of a request's
PHP function calls and ~4–5 ms (~8–11%) off PLP/PDP render in production, with behaviour
identical to the stock interceptor.
How it hooks in
Magento's compile-time interceptor generator, Magento\Setup\Module\Di\Code\Generator\Interceptor,
is instantiated via ObjectManager::create(), so it is replaceable by a plain DI
preference (etc/di.xml):
Magento\Setup\Module\Di\Code\Generator\Interceptor
→ Cresset\FusedInterceptors\Code\Generator\FusedInterceptor
setup:di:compile clears generated/code and reads di.xml live, so the preference
applies on the very first run — no priming compile, no post-processing, no file
rewriting. FusedInterceptor::_generateCode() emits the fused class; anything it can't
fuse safely falls back to the stock dynamic interceptor, so compilation can never break.
(A plugin on DiCompileCommand does not work — its execute() is protected and the
Setup module runs outside app interception. Replacing the generator is the correct hook.)
Components
| Class | Role |
|---|---|
Code\Generator\FusedInterceptor |
Overrides _generateCode(): extract chains → emit fused, else fall back to stock. |
Model\ChainExtractor |
Per-scope plugin chains for a type. One warmed PluginList per scope (global + every area); clean, non-accumulating, no subprocess. |
Model\CodeEmitter |
Turns the per-scope chains into fused PHP (pruning, scope dispatch, before/after threading, around → nested-closure onion, lazy resolve-once plugin caches). |
What the generated interceptor does
- Overrides only plugged methods (everything else inherited).
- No constructor — inherits the subject's, so the OM injects real deps unchanged. Plugins/scope are resolved lazily via the global OM at call time, so building the interceptor never forces a plugin to construct (no circular-dependency risk).
switchongetCurrentScope()only when the chain differs across scopes.- Faithful to
Interceptor::___callPlugins: before rewrites args (if ($r !== null)), after reassigns$result, around plugins get a real$nextclosure per chain segment. - Around chains minimise closure allocations: the outermost segment is inlined into the
method body (never passed as a
$next), and a terminal with no before/after is passed as the first-class callableparent::method(...)rather than a wrapper closure — ~50% fewer closures for a single around, ~28% for before+around+after+around. - Falls back to the stock dynamic interceptor for a method with a by-reference or variadic parameter.
Install
composer require cresset/module-fused-interceptors
bin/magento module:enable Cresset_FusedInterceptors
bin/magento setup:upgrade
bin/magento setup:di:compile # interceptors come out fused
Disable by removing the module (composer remove cresset/module-fused-interceptors
or the preference) and recompiling.
Requirements
- Mage-OS / Magento Open Source 2.4+ (Mage-OS
framework^3.0) - PHP 8.4 / 8.5
License
OSL-3.0 / AFL-3.0.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: OSL-3.0
- 更新时间: 2026-07-01