opencart源码学习(一)——业务逻辑核心controller
来源:互联网 发布:办公室有老鼠 知乎 编辑:程序博客网 时间:2024/05/16 11:10
近期拖鞋接手了一个opencart的二次开发项目,所以不可避免地要把opencart本身的业务逻辑看个清楚,这对于毫无php开发基础的拖鞋来说,无疑是个蛋疼而艰巨的任务。
于是,从自学php,到把opencart的主要业务逻辑看通看懂,前前后后花了近一个星期,其中一手度娘一手gedit的辛酸自不多说,末了觉得收益良多,经验不敢独享,当然也怕自己忘记,遂记于此处,分享如下:
1.概述
正如标题所述,opencart的业务逻辑核心是controller类,源码位置opencart/system/engine/controller.php。作为一个核心业务类,controller定义了opencart所有后台业务的基本特征,从动态收集页面元素,到按照模版渲染页面。
在横向上,它实现了“收集”与“渲染”的业务分离,在纵向上,它采用了层层嵌套的业务组织,从而使整个页面响应流程有条不紊地进行,清晰易用。以下也将主要从这两个方向,解释controller的这种设计特征。
2.横向的业务分离
controller的横向业务分离特征主要体现在render()函数。
foreach之后,紧接一个if else,判断当前controller所需模板是否存在,不存在则输出错误信息,此处我们主要看判断存在的支路,它完成了读取模板,并按照模板渲染页面的功能。
首先是extract()这个函数,度娘可知它是个php预定义函数,作用是把数组元素从键值形式转化成变量形式后,把它们统统置于当前的符号表中,举例来说,就是把数组中的a=>b转成$a=b后抛出,从而能使后面的代码使用$a(可视作临时变量,局限于当前作用域)。
从代码可知,作者正是通过使用这个神奇的函数,从而轻松地把之前存放在data中的执行结果“解包”出来,供后面require进来的模板“使用”。值得一提的是,这种“使用”过程事实上是被动的,是需要纳入模板设计者考虑的,关于这点我们随便打开一个默认模板目录(catalog/view/theme/default/template)下的模板就可以大概了解到,从data提取出的这些变量值,事实上恰恰确定了模板中所有用php书写的动态部分,也正因如此,作者才能用这么简单的几句代码就完成了controller的渲染。
此外,还有一个地方需要注意,关于ob_start(),ob_get_contents()与ob_end_clean()。ob其实就是缓冲区,ob_start()打开缓冲区后,此后代码的所有输出将全部放在这个用户不可见的缓冲区中,直到ob_end_clean()的出现,关闭并清除缓冲区。作者在此处用缓冲区存放渲染结果,然后再用ob_get_contents()返回缓冲区的输出内容到controller的output中,目的就是令渲染过程完成在缓冲区中,然后方便放于一个变量里,封装返回渲染结果。这对于controller纵向的层层嵌套是有重要意义的,下面也将述及这一点。
3.纵向的业务组织
controller的纵向业务组织特征是render()和getchild()的联合作用。上文已说了render(),此处重点说getchild(),下面将先理清其具体实现:
上文提过,这个函数将返回一个controller的output,条件是它需要一个child参数和一个可缺省的数组参数。这个child可以把它看成是一个controller子类的文件路径,这从它能作为action的构造参数就可以看出。
关于action,在这里我们先转过头去看看它的代码实现,它是一个同样放在engine目录下的类,其意义就是把一个controller子类的文件路径(也可能不是文件路径,而是一个精确到需调用函数的‘函数路径’),解释封装成一个指明了类名和需调用函数等“动作”信息的对象。当然,action的需调用函数通常会缺省,也就是当传入的路径参数的确是一个纯粹的文件路径时,action的需调用函数会默认指定为一个名为index的函数,一个所有controller子类都“约定”会有的函数。
关于index函数,我们先不管它的具体实现,以后会有相关的展开,现在只需知道它是一个通知controller子类对象准备相关信息,然后进行渲染工作的函数即可(好吧,其实这就是它的全部意义了……)。
有了这个概念,我们就可以回头看getchild()了。很明显的,new Action之后的一堆东西其实就是调用了controller子类对象的index,通知其进行渲染工作,并返回结果。
说完getchild,下面就可以展开对controller纵向特征的分析了:
首先,要说明的一点是,判断一个过程是否是嵌套机制,拖鞋习惯于关注两点,一是任务的下派,二是结果的返回,只要理清这两点,就可以很容易判断过程是否存在嵌套。
而在controller中,任务下派的过程体现在调用render时,遍历controller对象所属的每个child,并用getchild通知每个child执行工作,又因为child实际上是controller子类的对象,这个对象实现了一个准备了相关资料并调用render的index函数,所以这种通知child执行的工作事实上是层层下派的,由此,任务下派过程成立。
结果返回的过程则体现在返回getchild后,所有返回结果都存放在data数组中,而data在render中被用extract“解包”后,与模板共同作用渲染页面,然后再存放在output中。在这里考虑上文任务下派的层次关系,可以假定这个调用render的对象实际上是个controller子类对象,它的渲染任务是上一级controller分派下来的,那么,这个render应该是在这个子类对象的index中被调用,而index则在上一级controller的getchild中被调用。于是,在执行完index后,上一级controller的getchild把下一级的controller子类对象的output作为返回,从而完成逐级返回,由此,结果返回过程成立。
4.总结
要了解opencart的业务逻辑,controller的具体实现是绕不开的一道坎,而要了解controller的具体实现,拖鞋觉得从上面两个角度分析是比较好懂的,至少算是一种把灵活但凌乱的php流程化清晰化的努力,因此,才有了这篇博文。
PS.抱头多说一句,拖鞋典型新手,废话多排版乱难免,各位轻喷,欢迎指点。
- opencart源码学习(一)——业务逻辑核心controller
- opencart 业务逻辑核心controller
- SpringCache实现原理及核心业务逻辑(一)
- Ehcache注脚核心逻辑源码学习
- Spring IOC核心源码学习(一)
- Spring IOC核心源码学习(一)
- Spring IOC核心源码学习(一)
- SpringCache实现原理及核心业务逻辑(二)
- SpringCache实现原理及核心业务逻辑(三)
- ExtJs源码分析与学习—ExtJs核心代码(一)
- MVC模式中如何区分应用程序逻辑(Controller层)和业务逻辑(Model层)
- MVC模式中如何区分应用程序逻辑(Controller层)和业务逻辑(Model层)?
- 啃啃老菜:Spring IOC核心源码学习(一)
- 啃啃老菜:Spring IOC核心源码学习(一)
- MVC框架中的模型-视图分离问题(一) —— “你必将业务逻辑由显示中分离”
- 新闻发布项目——业务逻辑层(UserService)
- 新闻发布项目——业务逻辑层(newsTbService)
- 新闻发布项目——业务逻辑层(commentService)
- Visual Studio调试之符号文件
- linux下nc的使用
- 滨州学院CSDN高校俱乐部第三期公开课——移动互联网的前景与Android移动开发
- QT5.1.1中MinGW4.8的环境变量配置
- java.lang.IllegalStateException
- opencart源码学习(一)——业务逻辑核心controller
- 无人机六自由度仿真代码
- xCode4.6和xCode5 code theme,好看,不伤眼
- 23个设计模式之代理模式(2)动态代理
- java基础-反射 --通过反射 获取泛型实际类型参数
- 反步法+模糊参数估计设计永磁同步电机控制器(源代码)
- [HDU 4666]Hyperspace[最远曼哈顿距离][STL]
- C++中为什么要用虚函数、指针或引用才能实现多态?
- #R#R presentation and Shiny package