Magento2:插件和首选项之间的基本区别是什么?


47

我在magento2教程中同时使用了插件和首选项,两者都工作正常,但是它们之间的基本区别是什么。

插件代码:

1.1)在di.xml中添加一个插件声明:

<type name="Magento\Catalog\Model\Product">
<plugin name="magento-catalog-product-plugin" type="Training\Test\Model\Product" sortOrder="10"/>
</type>

1.2)创建一个插件类:

<?php
namespace Training\Test\Model;
class Product {
public function afterGetPrice(\Magento\Catalog\Model\Product $product, $result) {
return 5;
}
}

偏好代码:

2.1)创建一个首选项声明:

<preference for="Magento\Catalog\Model\Product"
type="Training\Test\Model\Testproduct" />

2.2)创建一个新的产品类:

<?php
namespace Training\Test\Model;
class Testproduct extends \Magento\Catalog\Model\Product
{
public function getPrice() {
return 3;
}
}

Answers:


58

首选项等效于从Magento 1重写类。它等效于说:“每当代码要求时ClassA,就给它们MyClassB。” MyClassB应该是的完整实现ClassA,再加上您在顶部添加或修改的任何行为。

与在Magento 1中一样,一次只能对一个类激活一个首选项(重写),除非您手动MyClassB将它们链接(例如extends OtherClassBOtherClassBextends ClassA)。

插件使您可以在要连接的类中的方法之前,周围或之后执行代码。您的插件类不会替换目标类,它也不是它的实例。你只要有方法before{method}around{method}after{method}其中获得在对于目标类{}方法适当的时间执行。

由于插件不能替代目标类,因此可以在一个类上同时激活任意数量的插件。Magento只是根据XML中的sortOrder参数一个接一个地执行它们。

因此,插件比首选项更加灵活。您应尽可能使用插件,除非绝对必要,否则应避免偏好重写类。

您可以在官方文档中了解有关插件如何工作以及如何使用它们的更多信息


优先级不等同于类重写。这是为接口提供默认实现的方法。
卡迪(Kandy)

1
@KAndy这可能是基本的预期目的,但是这样做的副作用是它们也适用于类重写。在语义上它们是相同的。Yogesh询问通过偏好进行班级改写的问题,以及他正在从事的基础知识练习指示您执行的操作。
瑞安·霍尔

12

简单来说

首选项用于覆盖类

插件用于在方法之前,之后和周围添加功能。

作为您的示例:

<preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\MyModule\Block\Product\ListProduct" /> 

每当代码询问ListProduct时,首选项表示

嘿,用 Vendor\MyModule\Block\Product\ListProduct 代替 Magento\Catalog\Block\Product\ListProduct

<type name="Magento\Catalog\Model\Product">
<plugin name="magento-catalog-product-plugin" type="Training\Test\Model\Product" sortOrder="10"/>
</type>

每当代码要求getPrice()时,插件都会说

getPrice() ,在您的 方法前后,前后使用我getPrice() 方法


1

简单来说 :

首选项用于指定接口的默认实现。

插件(Interceptor)用于扩展另一个类的公共方法的行为。

详细 :

首选项: 如果实现一个接口的类不止一个,那么在所有实现的类中指定默认的一个是很重要的。这是通过依赖项注入文件(di.xml)中的首选项节点完成的。

范例:

<preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\MyModule\Block\Product\ListProduct" /> 

此映射位于中app/etc/di.xml,因此对象管理器在全局范围内的Magento\Core\Model\Url任何地方都注入实现类Magento\Core\Model\UrlInterface

插件(拦截器):

假设一个类A具有methodA需要扩展功能的方法。然后,这是通过插件创建类APlugin而无需修改原始类而实现的A。类APlugin具有在所需方法之前,之后或周围运行的方法。

范例:

<config>
    <type name="Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStock">
        <plugin name="showOutOfStockValueChanged" type="Magento\Catalog\Model\Plugin\ShowOutOfStockConfig"/>
    </type>
</config>

此映射在app / etc / di.xml中。在类Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStock方法之前/之后/周围执行一种/ Magento\Catalog\Model\Plugin\ShowOutOfStockConfig几种类方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.