有多种方法可以覆盖类和方法。其中,在大多数情况下,使用类首选项可以被认为是最可行,最直接的方法。但是,用这种方法重写有时会引起冲突。为了帮助您处理此问题,引入了新的插件概念。这将有助于扩展方法而无需将类本身更改为类首选项方法。在本教程中,我们将向您展示如何使用plugin覆盖类。
每个模块都有一个全局的和特定的di.xml文件,可以根据作用域进行应用。以下是模块di.xml文件的路径:
Mageplaza/HelloWorld/etc/di.xml
Mageplaza/HelloWorld/etc/<area>/di.xml
也可以在di.xml文件中配置插件,并且在被覆盖的方法之前,之后和周围都会调用它们。下面是我们要执行以下操作时di.xml文件的示例:
<config>
<type name="Magento\Catalog\Api\Data\ProductInterface">
<plugin name="mageplaza_helloworld_catalog_product" type="Mageplaza\HelloWorld\Plugin\Model\Product" />
</type>
</config>
如何使用插件覆盖类
- 之前的方法
- 后方法
- 绕法
之前的方法
在未观察到的方法之前运行插件之前,如果未修改该方法,则必须在该方法接受的数组中返回相同的参数编号,否则返回null。扩展的方法必须在名称前加上前缀
<?php
namespace Mageplaza\HelloWorld\Plugin\Model;
class Product
{
public function beforeSetPrice(\Magento\Catalog\Model\Product $subject, $price)
{
$price += 10;
return [$price];
}
}
后方法
一旦调用了原始方法,将执行after方法。除了类对象之外,该方法还接受另一个参数,该参数还必须返回结果。正在扩展的方法必须具有类似的名称,其前缀为。
<?php
namespace Mageplaza\HelloWorld\Plugin\Model;
class Product
{
public function afterGetName(\Magento\Catalog\Model\Product $subject, $result)
{
$result .= ' (Mageplaza)';
return $result;
}
}
绕法
使用around方法时,原始方法将被包装。同样,此方法允许在原始方法之前和之后执行代码。它接受另一个参数receive是可调用的,它允许其他插件在链中调用。正在扩展的方法必须具有相似的名称,前缀为。
<?php
namespace Mageplaza\HelloWorld\Plugin\Model;
class Product
{
public function aroundSave(\Magento\Catalog\Model\Product $subject, \callable $proceed)
{
// before save
$result = $proceed();
// after save
return $result;
}
}
结论
总而言之,尽管使用插件确实存在一些局限性,因为它不能用于所有类型的方法,但它仍然是您可以考虑用于替代方法的理想解决方案