magento教程--如何创建和使用plugin
magento中的构造函数,一般是用来实现依赖注入,并且对依赖注入过来的对象,进行初始化。(其他作用,目前还没见到)

plugin是用来修改某个类中的public function的。通过di.xml来定义修改。通过这种修改的方式。即使这个类被其他class继承了。那也不会影响继承的那个 class。只会影响plugin在dim中指定修改的本class。
有点相当于。用另一个类对在本类进行内部public function的扩展。但是不影响本来的子继承类。before修改原生方法的参数。after修改原生方法的返回值。around对原生方法进行覆盖重写。
before的返回值(返回数组),就是原生方法的参数
after的参数就是,原生方法的返回值。after的返回值的类型要和原生方法一致。
视频地址:
https://www.youtube.com/watch?v=qZyU01xnGPE&list=PL9Q0S-CmtAhJVjwnK5ip6H84sCuRQcACY&index=35
https://segmentfault.com/a/1190000005084314 中文版本教程
https://www.mageplaza.com/magento-2-module-development/magento-2-plugin-interceptor.html
英文版教程
type可以按照下面这个命名规范,放在module下的plugin目录下 。这里可以填真实的类名,或者这是virtual type。



命名,首字母大写,然加前缀,如果方法的首字母是下划线,那就不用改,直接加前缀。
before就是在原方法之前执行的方法。它的返回值要作为原方法的参数,所以个数要保持一致。如果是多个,就返回一个数组。如果不修改原方法的参数,那就这个before方法就应该返回一个null
参数,第一个参数是observered class对象。第二个参数,就是要修改的那个对象的参数,复制过来就可以。
after就是在原方法之后执行的。所以要把原方法的返回值传入这个方法才可以。因为可以对他做进一步的修改。修改后得到的返回值的类型要和原方法返回值的类型一样。
参数,第一个参数也是observered class这个对象。第二个参数是原方法的返回值。第三后面的参数,如果要用到原方法的参数,就复制过来就可以。可以是一个,也可以是全部。
laravel的model中也有这个类似的方法,getxxx Attribute和setXXXAttribute
Using around methods allow you to override an observed method.
around是对原来方法的覆盖,一般 也不建议使用。
第一个参数observered class这个对象,第二个参数是一个回调函数。callable $proceed,第三个参数是原来那个方法的参数。
Around-Listener 方法的第一个参数是原生方法所属类的实例;第二个参数是下一个插件的类名或方法名。如果原生方法有参数,则以同一顺序依次跟在第二个参数之后。
第二个产生就是observered function,可以直接调用,就可以得到observered function的返回值了。需要把原先的参数传递进去。

插件的优先处理
当多个插件同时指向同一个原生方法时,将按以下顺序执行:
-
执行
sortOrder最小的插件的 Before-Listener 方法 -
执行
sortOrder最小的插件的 Around-Listener 方法 -
按
sortOrder值从小到大顺序执行插件的其他 Before-Listener 方法 -
按
sortOrder值从小到大顺序执行插件的其他 Around-Listener 方法 -
按
sortOrder值从大到小顺序执行插件的 After-Listener 方法
关于around的第二个参数的那个回调函数有点不太好理解
关于di.xml中配置文件的作用范围??

但是这个di.xml是在magento/model_category这个里面定义的

应该会把每个模块中的ETC下的di.xml合并,左右全局都可以用的di.xml
和传统的laravel有些不同
laravel中 ,url的参数是通过在控制器中获取的。所有的参数不管是post或者get都是要通过url来发送,那就肯定是要通过路由的。然后路由把参数再给到控制器,控制器来进行处理。
但是在magento中。为何url中的参数,通过phtml来获取,再发送给viewmodel呢?
也是通过控制器来得到的。不过控制器是$block了。viewmodel是助手函数了。不属于控制器的范畴,所以助手函数肯定没办法得到请求对象。只能借助跳板来传递参数了。

其实理解有误,如果你把blade模板编译过来,发现也是很多php代码,从控制器获取内容。
那真正的访问顺序是啥样的呢?可以看下php当初如何自己编写模板引擎的。。
如果不用viewmodel的话,把logic写在block里的话,那block里是直接可以获取到请求对象的,然后在请求对象中得到参数的。
但是如果用了viewmodel的话,可以把viewmodel看成laravel中的助手函数,它是没有权限得到请求对象的。所有要得到的话,只能通过phtml了
可以这样理解
url--->route---->controller.action-->xml--->block---->phtml--->veiwmodel(viewmodel是由phtml调用,相当于助手函数,所以viewmodel要得到参数,要通过phtml来传递。
phtml是可以直接从$block得到参数的。viewmodel只能注入到$block,它无法从$block内得到参数。)
可以把$block看成是phtml的action,viewmodel看成是phtml的助手函数。
要得到viewmodel对象必须要注入到$block中,通过$block来进行获取viewmodel对象(和助手函数的区别)
打开url---> 通过路由---->路由对url进行解析,解析成控制器和方法---->通知系统调用对应的控制器,找到具体的执行方法---->方法内部调用model,得到需要的数据----->(不用模板引擎的情况,用混编)--->在混编文件中用php脚本来的到自己要的数据,最后被action,include近来------>在action的最后,进行echo输出,(这个输入的header是默认的。如果需要输入其他的,需要修改header的内容。)。

这里传入的实参,也是getkey传入的那个实参,是一样的,是对它的实参进行了第一步的预处理。然后再返回给observered class function。

如果observered class function 的paramas有default value,那before的这个function也要有default value。


在另一个module内,可以停止其他module的plugin,直接找到名字,然后加disabled = true。
当在本module内修改别的module的时候,都要在module.xml内定义下执行顺序。要本module在其之后执行。
更多推荐

所有评论(0)