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的返回值了。需要把原先的参数传递进去。

 

 

插件的优先处理

当多个插件同时指向同一个原生方法时,将按以下顺序执行:

  1. 执行 sortOrder 最小的插件的 Before-Listener 方法

  2. 执行 sortOrder 最小的插件的 Around-Listener 方法

  3. 按 sortOrder 值从小到大顺序执行插件的其他 Before-Listener 方法

  4. 按 sortOrder 值从小到大顺序执行插件的其他 Around-Listener 方法

  5. 按 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在其之后执行。 

更多推荐