已阅读5页,还剩21页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
ECMall 2.X 架构分析与技术指南ECMall 2.X 架构分析与技术指南一、系统架构分析:根据文件目录结构分析得到ECMall为MVC系统架构。控制器(Controllers)分析:在ECMall中分2种控制器,FrontendApp(前端)和BackendApp(后端),我们可以依据基础控制器创建自己的控制器。控制器文件的命名规则:类名(首字母大写) + .app + .php;文件位置:一般放置在相应的app目录中;类名规则:类名+App访问规则:/index.php?app=控制器类&act=方法¶m=注意:第一个控制器,必须拥有自己的语言文件,如MallBaseApp的子类语言文件位于languagessc-gbk下,而模块Module类的语言文件则位于模块的文件夹中,即使语言文件中仅有return array()的空数组。若没有相应的语言文件,程序将会报错。现在我们试着写一个自己的控制器:get_info($id);/输出goods信息$result = print_r($goods_info);/此处的test自定义模型将在下面讲述,暂时略过;function test()$test = m(test);$data = array(name=建航,”name2”=”科技”);/name,name2对应表字段$test-addData($data);测试访问:/index.php?app=demo1&goods&id=3模型(Model)分析:ECMall模型分为业务模型与普通模型,二者皆继承自核心类的BaseModel模型;模型、插件的继承关系模型:可以理解为数据实体类,对应数据库表字段,一个实体表示一张表,每个实例为一行记录。ECMall的大部分模型与表有对应关系,仅业务模型没有表联系(操作业务如CRUD)。创建自己的模型:模型文件的命名规则:类名(首字母大写)+.model+.php;文件位置:一般放置在相应的/includes/models目录中; 类名规则:类名+Model调用规则:可能选用控制器对应模型的多入口方式 ,也可以选用控制器对应模型的单入口方式。首先建立一张表Test(id,name,name2);编写test.model.php,代码如下:_name;。*/* 增加数据演示* author kichijyo;* return void*/function addData($data)$this-add($data);/该处的add()继承自BaseModel类测试访问:/index.php?app=demo1&act=test下面我们试着建一对主、从表的模型关系:首先我们建2张表,一个是ecm_test从来(id,stu_id相对于ecm_test2表的外键,name),另一个为ecm_test2主表(stu_id相对于ecm_test2的主键,score)。根据约束,先删除从表,方可继续删除主表。对照这两张表开始建立模型,分别为:TestModel,Test2Model两个类:首先我们分析下eccoremodelmodel.base.php文件中的_getJoinString()方法中的几个case条件:switch($relation_infotype)case HAS_ONE:/一对一关系break;case BELONGS_TO:/一对多的从属关系break;case HAS_AND_BELONGS_TO_MANY:/多对多的从属关系break;我们注意到,仅有3个可用,分别为HAS_ONE,BELONGS_TO,HAS_AND_BELONGS_TO_MANY,意味着HAS_MANY不可以用来做多表查询。下面着重讲述一下eccoremodelmodel.base.php:define(HAS_ONE,1);/一对一关联define(BELONGS_TO,2);/属于关联define(HAS_MANY,3);/一对多关联define(HAS_AND_BELONGS_TO_MANY,4);/多对多关联多表查询中存在的左右关系整理如下(表示实体模型是否可用来操作多表查询):包含从属HAS_ONE BELONGS_TO HAS_MANY BELONGS_TO HAS_AND_BELONGS_TO_MANY HAS_AND_BELONGS_TO_MANY 虽然从HAS_ONE与BELONGS_TO两种方式执行操作多表查询的left join 不同,但是之后一经加入conditions即where条件过滤后,两个的结果完全相同了。例如:1、 一个人有一个身份证号,我们称一个人HAS_ONE(既有)身份证号,反过来一个身份证号属于一个人所有,我们称一个身份证号BELONGS_TO(从属反向)一个人。(一对一关系);2、 一个班级有多个学生,我们称一个班级HAS_MANY(既有)学生,一个学生只属于一个班级,我们称一个学生BELONGS_TO(从属反向)一个班级。(一对多关系);3、 一个学生可以选择多门课程,反过来一个课程可以被多个学生选择,我们对这两个实体模型皆用HAS_AND_BELONGS_TO_MANY。(多对多关系,既有又从属反向);关于这三种关系,模型中涉及几个重要的字段:“model”=”指明对应的模型名称”,“type”=”指明当前模型与对应模型的关系是三种关系中的哪一种?”,“ext_limit”=”又称联合限制ext(扩展的意思),本质为left join on and XXX”扩展的即是这个语句的XXX内容”,“foreign_key”=”对应模型中的外键”,“refer_key”=”当前模型中的主键,若与对应模型外键同名,可省略不写”,“reverse”=”当前模型相对于对应模型关系为BELONGS_TO的从属关系时需要填写这个反向指代关系,值为对应关系的数组key值”,“middle_table”=”当实体模型关系出现多对多时才会出现的中间关系表”Okay,我们开始模型设计:1、 主表模型:class Test2Model extends BaseModelvar $table = ”test2”;var $prikey = “stu_id”;/这里同样对应着写,Test2对应test之后写test表中相对于Test2的外键与referencevar $_relation = array(“has_test” = array(“model”=”test”,“type”=HAS_MANY,“foreign_key”=”stu_id”,“refer_key”=”stu_id”);2、 从表模型:class TestModel extends BaseModelvar $table = “test”;var $prikey = “id”;var $_relation = array(/关于关系,这里按对应来写,像test对应test2,而且test为从表,故belongs_to test2表/reverse 反向关系到test上“belongs_to_test2” = array(“model”=”test2”,“type”=BELONGS_TO,“revers”=”has_test”);3、 应用:class Jiang3App extends MallbaseAppfunction index()/因为仅有3个可用,分别为HAS_ONE,BELONGS_TO,HAS_AND_BELONGS_TO_MANY/故关系上选取拥有type为以上三个值的模型。$test = m(“test”);$sql = array(join=belongs_to_test2,conditions=test.stu_id);$arr = $test-find($sql);print_r($arr);4、 多对多应用:Course.model.phpclass CourseModel extends BaseModelvar $table = “course”;var $prikey = “id”;var $alias = “cour”;var $_name = “course”;var $_relation = array(“model”=”student”,“type”=HAS_AND_BELONGS_TO_MANY,“middle_table”=”stu_course”,“foreign_key”=”course_id”,“refer_key”=”id”,“reverse”=”learn_course”);Student.model.phpclass StudentModel extends BaseModelvar $table = “stu”;var $prikey = “id”;var $alias = “stu”;var $_name = “student”;var $_relation = array(“learn_course”= array(“model”=”course”,“type”=HAS_AND_BELONGS_TO_MANY,“middle_table”=”stu_course”,“foreign_key”=”stu_id”,“refer_key”=”id”,“reverse”=”join_student”);应用:class Jiang3App extends MallbaseAppfunction index()$course = m(“course”);$sql = array(join=join_student,conditions=cour.id=2,fields=stu_course.stu_id);$arr = $course-find($sql);print_r($arr);5、 模型验证:每个模型映射表结构,那么必然有相关的约束验证,模型中的$_autov(自动验证auto validate),此处的自动验证包括类如:required(是否必需),reg(正则验证)等内容。下面我们来看一个典型的验证模型:一个典型的表对应模型:class TestModel extends BaseModelvar $table = “test”;var $prikey = “id”;var $_autov = array(“title”=array(“required”=true,“filter”=”trim”),“description”=array(“required”=true,“filter”=”trim”);var $_relation = array(“has_test2”=array(“model”=”test2”,“type”=HAS_MANY,“foreign_key”=”pid”,“refer_key”=”id”);从上面我们看到有$table,$prikey,$_autov,$_relation这4个部分,扩展可以加上$_name,$_alias等;【延伸阅读】刚刚在上面讲述了join语句,这里有个地方需要大家注意:数据库在通过连接两张表或多张表来返回记录时,都会生成一张中间表,然后再将这张临时表返回给用户。在使用left join 时,on和where条件的区别:例如:两条SQL语句:1、 select * from tab1 left join tab2 on (tab1.size = tab2.size) where =AAA2、 select * from tab1 left join tab2 on (tab1.size = tab2.size and =AAA)假设有两张表:IdSize110220330表tab1sizename10AAA20BBB30CCC表tab2第一条SQL的过程:1、 先生成中间表 on 条件:tab1.size=tab2.sizeTab1.idTab1.sizeTab2.sizeT11010AAA22020BBB33030CCC44040DDD临时中间表2、 再对中间表过滤where条件:=AAATab1.idTab1.sizeTab2.sizeT11010AAA最终数据表结论:where条件是在临时表生成好后,再对临时表进行过滤的条件,这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的全部过滤掉了。第二条SQL的过程:1、 中间表on条件:tab1.size = tab2.size and =AAATab1.idTab1.sizeTab2.sizeT11010AAA220NullNull330NullNull最终数据表结论:on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。而inner join(也就是join的全称)没这个特殊性,则条件放在on中和where中,返回的结果集都是相同的。三表(更多表联合查询)join语句:select * from ecm_stu_s join ecm_stu_course sc join ecm_course c on s.id=sc.stu_id and sc.course_id=c.id where s.id=3;标注:ECMall目前暂不支持类似这样的三表链接查询语句。视图模板(Views)分析:首先让我们看一段商城首页的部分代码:include file=header.html$lang.hot_search:$keyword整体代码类似于此,这里有2个部分需要我们分析:1、include或foreach的Smarty语法,可以参考在、相关的Smarty资料;2、widgets挂件开发;让我们先来看下挂件的管理方法:1、 进入2.2后台,在这里寻找挂件管理界面:挂件管理界面2、 将设计好的挂件放入模板中;模板管理界面拖“挂”动作,这就是所谓的“挂”件在图中我们看到这块灰色的区域是我在themesmalldefaultindex.html文件中设置的,一般的我们会先设计出挂件将要拖入的区域,而后拖放挂件。这块区域的代码如下:注意两点:area与widget_type属性,其中area属性用来拖放挂件时给挂件配置文件指明从属方向,这里我们看下挂件拖放后形成的配置文件代码:文件定位:datapage_config里面有两个配置文件,default.gcategory.config.php(商品分类页)与default.index.config.php(商城首页),我们打开商城首页代码:部分截取:return array(widgets=array(_widget_235=array(name=kichijyo,options=NULL),_widget_877=array(name=notice,options=array(ad_image_url=data/files/mall/template/200908070207084061.gif,ad_link_url=),);上面是对每个挂件定义的ID值,继续向下滚动代码近于文档底部:config= array(mina = array(0=_widget_235),top_left = array(0=_widget_877,1=_widget_578,2=_widget_323),cycle_image= array(0=_widget_698);在这里可以看到,刚才在模板管理后台拖放挂件的时候,div标签中的area为上面这段配置代码指明了方向,就是说:widgets page=index area=mina里mina区域将包括ID为_widget_235这个的挂件,展示页面位于index上。widgets page=index area=cycle_image里cycle_image将包括ID为_widget_368的挂件,用于展示位于index的模板中。 既然系统都已经做好了配置文件,下面我们可以完善填充代码了,加入代码后开始:widgets page=index area=mina3、 挂件开发:3.1、数据调用形式概述:3.1.1、通用调用(ADODB类)/通用Adodb数据调用描述;包含有直接返回数组的getone,getcol,getrow,getall,除query(返回资源,非数组)/这里我使用了通用的Query方法 $db = db(test);/这里我们查询test表,注意没有表前缀$sql = “select * from ecm_test”;/注意这里有表前缀$quer = $db-query($sql);/这里和我们的PHP很类似,返回一个资源$arr = array();/创建一个空数组,用来存放数据while($row=$db-fetchrow($query)array_push($arr,$row);return $arr;/返回数组;下面准备进入widget模板做Smarty上面的SQL可以替换为:insert,delete,update等相关常规语句;3.1.2、内部模型调用(ECMall独有,需单独研究)使用内部模型有两步骤:一、建实体类(或业务模型);二、数据调用,比通用麻烦点,但是后面省心哦。下面继续:让我们来创建一个模型:class TestBModel extends BaseModelvar $table = test; /映射表名,必须字段,注意无前缀;var $prikey = id;/主键定义,必须字段function getData()/其它方法定义实例化时注意:$test=bm(test);注意用bm实例化;这里我用的BModel(操作业务模型),我们从前面的模型继承图知道,BModel继承自BaseModel,当然这里如果不使用操作业务模型,仅仅使用与表有映射关系的普通模型也是可以的,比如:class TestModel extends BaseModelvar $table = test;var $prikey = id;function getData()/其它方法定义实例化时使用:$test=m(test); /这里使用m来实例化;模型建立完,我们开始调用模型,可以在诸如挂件、控制器等地方使用,代码如下:以实体类为例:function index()$test = m(test);/实例化test模型/这里使用了模型中比较通用的find()方法,当然你也可以使用直接返回数组的get_info($id),get($array)等模型中的函数;下面的$query直接返回是数组,不是资源了,这点与ADODB的DB不同。$query = $test-find($array(conditions=id2,limit=1,order=id desc);$this-assign(arr,$query);$this-display(test.html);讲述到这里,数据CRUD部分算是分析完毕了;下面我们将讲述挂件设计3.2、挂件代码设计:挂件的组织形式按照文件夹组织,位于externalwidgets目录下,每个文件夹对应一个挂件,每个文件夹中包含4个文件:config.html(配置界面模板)、main.widget.php(挂件主程序文件)、widget.html(挂件显示模板)、.php(挂件信息文件)。我们不必自己创建,只要直接复制一个挂件文件夹即可。然后着手修改里面的代码就Okay了。文件分析:3.2.1、.php(信息配置文件):return array(name=kichijyo,/给挂件起名,注意应与包含文件夹的名字相同;display_name=客齐集,/模板管理界面显示的挂件名字;author=Kichijyo Team,website=,version=1.0,desc=显示测试数据内容,/挂件描述Description;configurable=true/配置本挂件是否可以配置,false时挂件不能被傻瓜配置;);3.2.2 main.widget.php(挂件主程序):a) 类的命名规则:挂件文件夹名(首字母大写)+widget;类中的$_name字段,赋值为挂件文件夹名;b) 需要关注的几个方法:c) _get_data():该方法用来返回挂件需要展示的数据;d) get_config_datasrc():该方法用来获取配置界面所需的展示数据;e) function parse_config($input):该方法用来处理配置页面传入的数据;f) 需要关注的变量:$widget_data(相当于Smarty.assign()之后的数据),$options配置的数组数据;g) parse_config($input):该方法是配置数据的保存处理方法,默认它将数据保存到datapage_configdefault.index.config.php或另外一个商品文件中,具体的保存位置依据具体挂件模板来差别,index对应index,商品分类的对应商品分类,也就是说,它的数据保存不面向数据库,它以文本文件的形式保存在了datapage_config下的php文件中。如果需要保存到数据库,请自行加入数据库操作的实现处理。3.2.3、挂件操作流程图:挂件处理流程图3.2.4、主程序简易代码实现:class KichijyoWidget extends BaseWidgetvar $_name = kichijyo;/必须与文件夹同名function _get_data()return $this-options;/返回$widget_data数组给widget.html模板/从datapage_config文件夹中的相应PHP文件中获取相关的options数组,并以$options来填充配置页面模板function get_config_datasrc()$this-options=stripslashes_deep($this-options);$this-assign(options,$this-options);/处理配置页面传入的数据,并将该数据返回给$options数组,即保存到datapage_config文件夹下的PHP文件中;function parse_config($input)return $input;3.2.5、其它文件简述:config.html:请输入您的姓名:请输入您的描述:需要注意的是,这里不需要任何method=post等,仅仅写少许必要代码即可,ECMall连提交按钮都给做好了。widget.html:$widget_ and $widget_data.description这里直接上Smarty模板语法,一切皆Okay。至此,挂件部分描述完毕;下一节模块开发4、 模块开发模块的组织形式:externalmodules目录下创建模块文件夹,模块内的组织文件包括:a) index.module.php(前端控制器)b) admin.module.php(后端控制器)c) .php(模块配置信息文件)d) 模板templates文件夹e) 语言文件夹languages对于安装与卸载文件不是必须文件,我们略过。简要浏览下模块控制器adminappmodule.app.php这里有Install,Uninstall,Manage,Configer等等方法。感兴趣的朋友,可以研究一下哦。下面开始我们的开发之旅,首先和挂件一样,我们根本不需要自己逐一创建文件,只要复制一个已经有的模块文件夹并重命名即可。这里我复制DataCall文件夹并重命名为Kichijyo。步骤:1 修改模块配置文件M.php; kichijyo,/这里应保证与模块文件夹同名。/这里是调用语言配置文件/externalmoduleskichijoylanguagessc-utf-8common.php/或languagessc-utf-8adminmodule.lang.phpname = Lang:get(data_call),desc =Lang:gete(datacall_desc),version=2.0,author =Kichijyo Team,Website =,menu=array( array( text = Lang:get(datacall_manage), act=index,),),);?通过上面的设置,我们在模块管理界的安装连接上已经改变了:/admin/index.php?app=module&act=install&id=kichijyo通过id=kichijyo使得安装模块指向了我们新创建的Kichijyo。下面是部分的语言文件:externalmoduleskichijyolanguagessc-utf-8common.lang.php”这是客齐集演示用模块”, data_call=客齐集模块, manage_data=管理, add_goods=新增商品调用, belong_type=所属类型, handler=操作, data_goods=商品数据); ? 2 修改前端控制器Index.module.php所有的模块Module都是ECBaseApp的子类,即模块也是控制器;类的命名规则:模块名(首字母)+Module 扩展自 IndexBaseModule。?php/前端访问形式往往是体现为JSON的数据调用形式,如:/可以用来给外部系统提供js的数据调出。class KichijyoModule extends IndexbaseModule /index()为默认方法,延续了所有的控制器的特征; function index() $db=db(“test”); $sql=”select * from cem_test”;$query=$db-query($sql); $result=array(); while($row=$db-fetchrow($query) $result=$row; $this-assign(“result”,ecm_json_encode($result);/注意这里的ECM_JSON$this-display(“admin/datacall.index.html”); ?与上部匹配的前端调用模板,我们可以这样写:externalmoduleskichijyotemplatesadmindatacall.index.htmlvar result=$result;for(var i=0;iresult.length;i+) document.write(resulti“description”+”);此种方式为JS嵌入式的写法,上面皆是JS语法规则;当我们把代码加入到需要跨系统调用数据的页面时,系统将执行上面的这段JS代码,将数据调出给外部系统。3 修改后端的控制器的Admin.module.php类的命名规则:模块名(首字母)+Module 扩展自AdminBaseModule。query($sql); $result=array(); while($row=$db-fetchrow($query) $result=$row;$this-assign(“result”,$result);$this-display(“datacall.form.html”);/这里指定模块管理链接点开后所显示的模板页面,建议直接建一个kichijyo.admin.html,比用这个怪怪的名字好多了,是么?? 与后端控制器相对应的模板代码随意写几行,就比如:$lang.data_call就欧乐。语言包language都可以在模板中直接调用哦,这里就不说了。略过300行插件开发打开extearnalplugins目录层级,依然随意复制一个插件文件夹,省去了我们很多的麻烦,里面的东西都写好了。我们可以将新的文件夹命名为Kichijyo.发现文件夹中有2个文件爱你,一个是插件主文件Main.plugin.php,另外一个是插件信息文件,.php。修改P.phpreturn array( id=kichijyo,/这里必须与插件的文件夹同名; hook=on_run_action,/这个地方是钩子,有4个枚举值,分别为On_run_action(在action之前)、End_run_action(在action之后)、On_display(在显示之前)、End_display。具体含义请查阅官方说明 name=访问计数插件,desc=当网站前端访问时,系统自动增1,以计数。,author=Kichijyo Team,version=1.0,/下面的config配置类型包括:text,textarea,select,radio,checkbox,相关内容查阅官方说明config=array( “text”=array( “text”=”广告标题”, “type”=”text”,),“sexy”=array(“type”=”radio”,“text”=”性别”,“name”=”configsex”,/注意这里可以不写sexy“items”=array(“男”=”yes”,”女”=”no”,),),),),下面开始我们的主程序文件开发,修改Main.plugin.php类的命名规则:插件名(首字大写)+Plugin扩展自BasePlugin。我们只要修改execute方法即可,该方法是插件的执行方法。class KichijyoPlugin extends BasePlugin function execute() if(defined(IN_BACKEND)& IN_BACKEND=true) return;/后台无需执行,如果是false则不中断流程,为true则中断流程。elseif($storeid=intval(current(array_keys($_GET) $name=$this-configtext; $description=$this-configsex; $db=db(test);$sql=”insert into ecm_test(name,description)values ($name,$description);”;$db-query($sql);6支付方式开发 所有支付包位于includespayments下。每个包标示一个支付方式,包内有至少包括:1 信息文件:.php2 主程序文件:包名(支付方式名)+payment.php3 支付方式相对应的Logo文件; 每种开发方式的对应语言文件位于:languagessc-utf-8payment(这里就UTF8大编码而言) 相应文件命名为:支付方式+lang.php; 继承关系:每个支付方式扩展自:BasePayment(parent class:Object); 在类的实现方面,以Aplipay为例: class AlipayPayment extends BasePayment /必须实现$_gateway(网关),$_code(支付标
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 消防设备维修管理与服务方案
- 2025四川内江冠泰贸易有限公司人员招聘2人笔试历年备考题库附带答案详解试卷3套
- 父亲公务员考试试题及答案
- 2025云南电力公司招聘62人笔试历年难易错考点试卷带答案解析试卷3套
- 2025中国建筑股份有限公司岗位招聘1人(审计部)笔试历年备考题库附带答案详解试卷3套
- 污水处理设施建设项目施工方案
- 第三单元第14课《智能创意》教学设计 2024-2025学年浙教版(2020)初中信息技术八年级下册
- 赤峰市公务员编制考试试题及答案
- 无机酸化合物生产线项目技术方案
- 城市路网打通工程施工方案
- 京东集团员工手册
- JT-T-1045-2016道路运输企业车辆技术管理规范
- 国开(甘肃)2024年春《地域文化(专)》形考任务1-4终考答案
- (高清版)JTGT 3331-04-2023 多年冻土地区公路设计与施工技术规范
- 水处理药剂采购投标方案
- 冬季基坑施工方案及措施
- 团员知识培训课件
- 大学生资源循环科学与工程职业生涯规划
- 石油行业安全生产标准化导则与实施规范
- 机械毕业设计-番茄打浆机设计
- 实验室质量管理体系建立与运行课件
评论
0/150
提交评论