creatuity/magento2-interceptors

Creatuity 编译拦截器模块

1.3.4 2024-04-18 12:25 UTC

This package is auto-updated.

Last update: 2024-09-18 13:35:08 UTC


README

关于

此组件更改了 Magento 2 生成拦截器类的方式(允许插件协同工作的机制)。

它不是生成模板代码,而是使用源代码信息编译拦截器。这使得插件运行更快,由于 Magento 使用了大量的插件,甚至在其核心部分,它可以将请求时间降低约 10%。这在存在大量非缓存 PHP 逻辑的地方很重要(例如,管理面板运行得更快)。

默认方法使用在几乎所有方法上调用的代码来查看是否有任何插件连接,在生成的代码中这不需要,并且减少了调用堆栈。

直接调用插件也使得代码更容易调试,更容易找到错误。

此插件生成的拦截器与 Magento 默认生成的拦截器100%兼容,因此无需更改您的插件。

版本

由于 Magento 2.4 引入了与拦截器生成器不兼容的更改,因此此模块为两个 Magento 版本都设有单独的分支

  • 使用 1.3.* 用于 Magento 2.4(分支:master)
  • 使用 1.2.* 用于 Magento 2.3(分支:magento23)

配置

此模块添加以下首选项以在开发者模式下运行

<preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="Creatuity\Interception\Generator\CompiledInterceptor" />

以下首选项用于在生产或默认模式下运行

<preference for="Magento\Setup\Module\Di\Code\Generator\Interceptor" type="Creatuity\Interception\Generator\CompiledInterceptor" />
<preference for="Magento\Setup\Module\Di\Compiler\Config\Chain\InterceptorSubstitution" type="Creatuity\Interception\Generator\CompiledInterceptorSubstitution" />

这些默认在模块 di.xml 中启用。

然而,此模块不会修改默认的生成方法,因此您可以覆盖上述首选项以回退到默认机制的所有或所选模式。

技术细节

而不是像这样在运行时读取插件配置的拦截器

public function methodX($arg) {
    $pluginInfo = $this->pluginList->getNext($this->subjectType, 'methodX');
    if (!$pluginInfo) {
        return parent::methodX($arg);
    } else {
        return $this->___callPlugins('methodX', func_get_args(), $pluginInfo);
    }
}

此生成器生成静态拦截器如下

public function methodX($arg) {
    switch(getCurrentScope()){
        case 'frontend':
            $this->_get_example_plugin()->beforeMethodX($this, $arg);
            $this->_get_another_plugin()->beforeMethodX($this, $arg);
            $result = $this->_get_around_plugin()->aroundMethodX($this, function($arg){
                return parent::methodX($arg);
            });
            return $this->_get_after_plugin()->afterMethodX($this, $result);
        case 'adminhtml':
            // ...
        default:
            return parent::methodX($arg);
    }
}

优点

  • 更容易调试。

    • 如果您在调试时遇到过 ___callPlugins,您应该知道在插件中调试问题有多么痛苦。
    • 生成的代码带有 PHPDoc,以便在 IDE 中更容易调试
  • 最快的响应时间(开发者和生产模式中快 5%-15%)

    • 调用堆栈中没有冗余的 ___callPlugins 调用。
    • 没有插件的方法根本不会在父类中覆盖。
  • 作为模块实现,可以轻松回退到默认的 Generator\Interceptor

缺点

  • 每次在 etc 插件配置中做出更改后,都需要清除 generated/code/*var/cache/*
  • 由于它不在运行时加载插件,因此可能无法在将插件插入核心 Magento 类(如 PluginsList 等)的边缘情况下工作。