Magento 2 Plugin - Interceptor - Magento 2插件 - 拦截器php
Magento 2 Plugin is a technical plugin for your better writing code. Interception Plugin is referred to a little magento 2 extension that allows editing the behavior of any public class or method by intercepting a function call and running code either before or after or around the function call. By using this Magento 2 Plugin Interception, you can modify the behavior of a class while there is no need to change the class directly.
html
Magento 2插件是一个技术插件,能够更好地编写代码。拦截插件被称为一个小的magento 2扩展,它容许经过在函数调用以前或以后拦截函数调用和运行代码来编辑任何公共类或方法的行为。经过使用此Magento 2插件拦截,您能够修改类的行为,而无需直接更改类。git
Maybe you still think the observers can help you do that fluently but some differences need to be pointed out. Particularly, not only create functions of a class using dependency injection but Interception plugin can also be confirmed with a sortOrder, that allows checking the chain and order on which plugins run. That is the reason why this plugin doesn’t make the class change and doesn’t have any conflict with one anothergithub
也许你仍然认为观察者能够帮助你流利地作到这一点,但须要指出一些差别。特别是,不只使用依赖注入建立类的函数,并且还可使用sortOrder确认Interception插件,该sortOrder容许检查连接和运行插件的顺序。这就是为何这个插件不会使类更改而且彼此之间没有任何冲突的缘由编程
1.Magento 2插件的好处设计模式
对于像您同样的模块开发人员,Magento 2 Interception插件容许:
缓存
若是您从未有过以这种方式建立系统的经验,那么当您对性能特征感到困惑时,并不奇怪。
但与Mageplaza开发团队合做,他们对专业知识充满信心,知道应该为这项工做应用哪些软件设计模式。
在本主题中,可能会给出不多的拦截器模式,所以若是您须要获取更多信息或本帖子范围内未包含的任何问题,请在此处与咱们联系。app
2.Magento 2插件的限制
什么状况Magento 2 Interception插件没法使用?
函数
3.建立Magento 2新插件的指南性能
<config> <type name="{ObservedType}"> <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false"/> </type> </config>
解释:
1.必需的选项:
type name:输入须要遵循的类或接口的名称。
plugin name:标识插件的任意插件名称。还用于合并插件的配置。
plugin type:填写插件类的名称或其虚拟类型。您能够为此字段引用如下命名约定:\Vendor\Module\Plugin\<ModelName>Plugin。
2.可选选项:
plugin sortOrder:当插件调用进程中的其余相同方法时设置顺序。
plugin disabled:这容许您快速启用或禁用插件。做为默认配置,所选值为false。使用此属性可禁用di.xml文件中的核心或第三方插件。
3.以下例所示,咱们将编辑 app\code\Mageplaza\HelloWorld\etc\di.xml, 您须要插入代码段:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd"> <type name="Mageplaza\HelloWorld\Controller\Index\Example"> <plugin name="Mageplaza_HelloWorld_Plugin" type="Mageplaza\HelloWorld\Plugin\ExamplePlugin" sortOrder="10" disabled="false" /> </type> </config>
例如,下面的代码定义了类型名称,咱们在 app/code/Mageplaza/HelloWorld/Controller/Index/ /建立了Example.php文件
内容以下:
<?php namespace Mageplaza\HelloWorld\Controller\Index; class Example extends \Magento\Framework\App\Action\Action { protected $title; public function execute() { echo $this->setTitle('Welcome'); echo $this->getTitle(); } public function setTitle($title) { return $this->title = $title; } public function getTitle() { return $this->title; } }
使用插件名称,咱们在 app/code/Mageplaza/HelloWorld/Plugin/ /建立了Example.php文件:
内容以下:
<?php namespace Mageplaza\HelloWorld\Plugin; class ExamplePlugin{ }
插件是经过在方法以前,以后或周围使用代码来扩展或编辑公共方法行为的好方法。
首先,请获取一个对象,该对象提供对被观察方法类的全部公共方法的许可。
插件中的3种方法
1. before - beforeDispatch()
2. around - aroundDispatch()
3. after - afterDispatch()
要应用before方法来修改观察方法的参数的话,能够返回修改后的参数。若是有多个参数,则返回将根据这些参数的范围执行。若是返回无效,则意味着不该修改被观察方法的参数。以下:
<?php namespace Mageplaza\HelloWorld\Plugin; class ExamplePlugin { public function beforeSetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $title) { $title = $title . " to "; echo __METHOD__ . "</br>"; return [$title]; } }
<?php namespace Mageplaza\HelloWorld\Plugin; class ExamplePlugin { public function afterGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $result) { echo __METHOD__ . "</br>"; return '<h1>'. $result . 'Mageplaza.com' .'</h1>'; } }
3. Around methods(围绕方法):around方法容许代码在observe方法以前和以后运行,所以您能够覆盖方法。这些方法必须与观察到的名称具备相同的名称,而前缀标签为“around”。
<?php namespace Mageplaza\HelloWorld\Plugin; class ExamplePlugin { public function aroundGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, callable $proceed) { echo __METHOD__ . " - Before proceed() </br>"; $result = $proceed(); echo __METHOD__ . " - After proceed() </br>"; return $result; } }
4. Check the result (检查结果):ExamplePlugin.php的全部内容以下:
<?php namespace Mageplaza\HelloWorld\Plugin; class ExamplePlugin { public function beforeSetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $title) { $title = $title . " to "; echo __METHOD__ . "</br>"; return [$title]; } public function afterGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $result) { echo __METHOD__ . "</br>"; return '<h1>'. $result . 'Mageplaza.com' .'</h1>'; } public function aroundGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, callable $proceed) { echo __METHOD__ . " - Before proceed() </br>"; $result = $proceed(); echo __METHOD__ . " - After proceed() </br>"; return $result; } }
在此以后,请刷新缓存并检查结果。它会像这样显示出来
若是您的插件是经过与参数匹配的方法调用的,它也必须与它们匹配,同时,您须要仔细遵循它们。在此过程当中,请注意方法的原始签名以及默认参数和建议类型。
例如,应用如下代码来标识能够为 nullable:的 SomeType 类型的参数:
<?php namespace Mageplaza\HelloWorld\Model; class MyUtility { public function save(SomeType $obj = null) { //do something } }
若是你用下面的插件包装这个方法:
<?php namespace Mageplaza\HelloWorld\Plugin; class MyUtilityPlugin { public function aroundSave(\Mageplaza\HelloWorld\Model\MyUtility $subject, \callable $proceed, SomeType $obj) { //do something } }
注意: Missing = Null
若是您将该方法与null一块儿调用,则PHP会产生致命错误(fatal error),由于您的插件中不容许使用插件null。
此外,遵循方法调用的插件中的参数很是重要。
但若是不关心参数,请使用 use the variadics and argument unpacking 来完成此操做:
<?php namespace Mageplaza\HelloWorld\Plugin; class MyUtilityPlugin { public function aroundSave(\Mageplaza\HelloWorld\Model\MyUtility $subject, \callable $proceed, ...$args) { //do something $proceed(...$args); } }
Set priority for plugins (设置插件的优先级):
sortOrder 选项容许 将正在观察相同方法的插件放入队列中。
当方法开始调用以前,以后或周围时,插件将逐个应用。
4. 插件实例:Visit-访问 https://github.com/mageplaza/magento2-samples/tree/master/sample-module-interception
做者翻译:徐锅转发请注明来源。翻译来源:https://www.mageplaza.com/magento-2-module-development/magento-2-plugin-interceptor.html