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