ECMALL完整教程.doc_第1页
ECMALL完整教程.doc_第2页
ECMALL完整教程.doc_第3页
ECMALL完整教程.doc_第4页
ECMALL完整教程.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Ecmall的详细分析-系统请求跳转分析ecmall的程序的大致结构,如图所示:根据ecmall的程序结构图,你可以清楚的知道ecmall的五脏六腑!ecmall的五脏六腑然后,根据我的学习,觉得其中一些值得我学习的地方,一一提取出来,对它进行分析,与理解。做如下几个问题的处理:需要分析的问题:1、系统请求跳转分析2、数据库关系模型的实现3、登录用户信息$this-visitor-get(“user_id”)的实现4、模板解析分析5、页面json对象传输实现6、 缓存分析这里需要提出的是:笔者也是在慢慢的学习它,难免会有不对之处,欢迎大侠们拍转,提出宝贵的意见!谢谢1、系统请求跳转分析:对于这个问题,我们要首先看看下面的这段代码:Php代码1. index.php: 2.3. include(ROOT_PATH./eccore/ecmall.php); 4. /*启动ecmall*/ 5. ecmall:startup(array( 6. default_app=default, 7. default_act=index, 8. app_root=ROOT_PATH./app, 9. /加载系统所需要的基础类 10. external_libs=array( 11. ROOT_PATH./includes/global.lib.php, 12. ROOT_PATH./includes/libraries/time.lib.php, 13. ROOT_PATH./includes/ecapp.base.php, 14. ROOT_PATH./includes/plugin.base.php, 15. ROOT_PATH./app/frontend.base.php, 16. ), 17. ); 18.19.20. ecmall.php 21.22. classecmall 23. 24. /*启动*/ 25. functionstartup($config=array() 26. 27. /*加载初始化文件*/ 28. require(ROOT_PATH./eccore/controller/app.base.php);/基础控制器类 29. require(ROOT_PATH./eccore/model/model.base.php);/模型基础类 30.31. if(!emptyempty($configexternal_libs) 32. 33. foreach($configexternal_libsas$lib) 34. 35. require($lib); 36. 37. 38. /*数据过滤*/ 39. if(!get_magic_quotes_gpc() 40. 41. $_GET=addslashes_deep($_GET); 42. $_POST=addslashes_deep($_POST); 43. $_COOKIE=addslashes_deep($_COOKIE); 44. 45.46. /*请求转发*/ 47. $default_app=$configdefault_app?$configdefault_app:default; 48. $default_act=$configdefault_act?$configdefault_act:index; 49.50. $app=isset($_REQUESTapp)?trim($_REQUESTapp):$default_app; 51. $act=isset($_REQUESTact)?trim($_REQUESTact):$default_act; 52.53. $app_file=$configapp_root.”/$app.app.php”; 54. if(!is_file($app_file) 55. 56. exit(Missingcontroller); 57. 58.59. require($app_file); 60. define(APP,$app); 61. define(ACT,$act); 62. $app_class_name=ucfirst($app).App; 63.64. /*实例化控制器*/ 65. $app=new$app_class_name(); 66. c($app); 67. $app-do_action($act);/转发至对应的Action 68. $app-destruct(); 69. 70. 71.72. /根据app后面所跟的参数,来判断加载对应的控制器类文件,类文件在app文件夹下,对应名称与参数相同,act 后面的参数是对应控制器中的操作方法处理请求 73. /而对应的动作中,会有一个判断:if(!IS_POST)请求前的页面内容的显示else请求后的表单处 理及处理完成后的页面跳转。其中包括使用json处理数据 74. /这里需要提出的是:在控制器中: 75. $this-assign(order,$order_info);/向模板页传递所需要参数的值 76. $this-display(buyer_order.confirm.html);/跳转到哪个页面 77. $this-json_result($new_data,confirm_order_successed);/使用json的方式传递参数,然后在页面上使用javascript处理请求的跳转 Ecmall的详细分析2-数据库关系模型的实现对于数据库关系模型的分析,我觉得需要从两个函数说起:/获取一个模型function &m($model_name, $params = array(), $is_new = false)static $models = array();$model_hash = md5($model_name . var_export($params, true);if ($is_new | !isset($models$model_hash)$model_file = ROOT_PATH . /includes/models/ . $model_name .model.php;if (!is_file($model_file)/* 不存在该文件,则无法获取模型 */return false;include_once($model_file);$model_name = ucfirst($model_name) . Model;if ($is_new)return new $model_name($params, db();$models$model_hash = new $model_name($params, db();return $models$model_hash;/获取一个业务模型function &bm($model_name, $params = array(), $is_new = false)static $models = array();$model_hash = md5($model_name . var_export($params, true);if ($is_new | !isset($models$model_hash)$model_file = ROOT_PATH . /includes/models/ . $model_name .model.php;if (!is_file($model_file)/* 不存在该文件,则无法获取模型 */return false;include_once($model_file);$model_name = ucfirst($model_name) . BModel;if ($is_new)return new $model_name($params, db();$models$model_hash = new $model_name($params, db();return $models$model_hash; 所谓模型,则是一个一个的数据实体,换句话说就是一个数据表,你可以基于这个模型,调用model.base.php中的数据库操作函数来对数据进行增、删、改、查的操作。这里的业务模型,是在实体模型基础上,再继承一次,然后对一些方法进行重写。系统中只有三个实体有业务模型:推荐类型 recommend;商品数据模型 goods;商品分类业务模型 gcategory;具体操作例子:/物品表的操作:$model_goods = & m(goods);$goods_info = $model_goods-get($goods_id); 这里需要解释一下对于数据模型的操作是怎样的一个函数调用过程:首先:$model_goods = &m(goods);我们看一下&m()函数的代码,其中var_export()函数则是将传进来的实体,返回相应的实体类对象,因为所有的model都继承至model.base.php中的BaseModel类,这个类中定义了基本所有的操作函数,因此$model_goods对象可以对数据库进行相应的操作。而我们再看看goods.model.php中的GoodsModel的代码: class GoodsModel extends BaseModelvar $table = goods;var $prikey = goods_id;var $alias = g;/缩写var $_name = goods;var $temp; / 临时变量var $_relation = array(/ 一个商品对应一条商品统计记录has_goodsstatistics = array(model = goodsstatistics,type = HAS_ONE,foreign_key = goods_id,dependent = true),/ 一个商品对应多个规格has_goodsspec = array(model = goodsspec,type = HAS_MANY,foreign_key = goods_id,dependent = true),/ 一个商品对应一个默认规格has_default_spec = array(model = goodsspec,type = HAS_ONE,refer_key = default_spec,foreign_key = spec_id,),/ 一个商品对应多个属性has_goodsattr = array(model = goodsattr,type = HAS_MANY,foreign_key = goods_id,dependent = true),/ 一个商品对应多个图片has_goodsimage = array(model = goodsimage,type = HAS_MANY,foreign_key = goods_id,dependent = true),/ 一个商品只能属于一个店铺belongs_to_store = array(model = store,type = BELONGS_TO,foreign_key = store_id,reverse = has_goods,),/ 商品和分类是多对多的关系belongs_to_gcategory = array(model = gcategory,type = HAS_AND_BELONGS_TO_MANY,middle_table = category_goods,foreign_key = goods_id,reverse = has_goods,),/ 商品和会员是多对多的关系(会员收藏商品)be_collect = array(model = member,type = HAS_AND_BELONGS_TO_MANY,middle_table = collect,foreign_key = item_id,ext_limit = array(type = goods),reverse = collect_goods,),/ 商品和推荐类型是多对多的关系 todobe_recommend = array(model = recommend,type = HAS_AND_BELONGS_TO_MANY,middle_table = recommended_goods,foreign_key = goods_id,reverse = recommend_goods,),);var $_autov = array(goods_name = array(required = true,filter = trim,),);这里贴出了实体goods模型类中的内容,先是表格的属性,再就是goods与其它实体之间的关联关系的定义。然后我们再看看这个函数,它是BaseModel构造函数里调用的方法,对对象中的基础变量进行初使化:function BaseModel($params, $db)$this-db =& $db;!$this-alias & $this-alias = $this-table;$this-_prefix = DB_PREFIX;$this-table = $this-_prefix . $this-table;if (!emptyempty($params)foreach ($params as $key = $value)$this-$key = $value; 大家已经看出$_relation 中间是此实体的关联信息,然后在BaseModel类中的一个函数:function _getJoinString($relation_info)switch ($relation_infotype)case HAS_ONE:/$model =& m($relation_infomodel);/* 联合限制 */$ext_limit = ”;$relation_infoext_limit & $ext_limit = AND . $this-_getExtLimit($relation_infoext_limit);/* 获取参考键,默认是本表主键(直接拥有),否则为间接拥有 */$refer_key = isset($relation_inforefer_key) ? $relation_inforefer_key : $this-prikey;/* 本表参考键=外表外键 */return ” LEFT JOIN $model-table $model-alias ON $this-alias.$refer_key=$model-alias.$relation_infoforeign_key$ext_limit”;break;case BELONGS_TO:/* 属于关系与拥有是一个反向的关系 */$model =& m($relation_infomodel);$be_related = $model-getRelation($relation_inforeverse);if (emptyempty($be_related)/* 没有找到反向关系 */$this-_error(no_reverse_be_found, $relation_infomodel);return ”;$ext_limit = ”;!emptyempty($relation_infoext_limit) & $ext_limit = AND . $this-_getExtLimit($relation_infoext_limit, $this-alias);/* 获取参考键,默认是外表主键 */$refer_key = isset($be_relatedrefer_key) ? $be_relatedrefer_key :$model-prikey ;/* 本表外键=外表参考键 */return ” LEFT JOIN $model-table $model-alias ON $this-alias.$be_relatedforeign_key = $model-alias.$refer_key$ext_limit”;break;case HAS_AND_BELONGS_TO_MANY:/* 连接中间表,本表主键=中间表外键 */$malias = isset($relation_infoalias) ? $relation_infoalias : $relation_infomiddle_table;$ext_limit = ”;$relation_infoext_limit & $ext_limit = AND . $this-_getExtLimit($relation_infoext_limit, $malias);return ” LEFT JOIN $this-_prefix$relation_infomiddle_table $malias ON $this-alias.$this-prikey = $malias.$relation_infoforeign_key$ext_limit”;break;/* 模型相关常量定义 */define(HAS_ONE, 1); /一对一关联define(BELONGS_TO, 2); /属于关联define(HAS_MANY, 3); /一对多关联define(HAS_AND_BELONGS_TO_MANY, 4); /多对多关联define(DROP_CONDITION_TRUNCATE, TRUNCATE); /清空从这个函数中,我们可以看到,对于不同的关联关系,它会返回不同的关联时的查询语句片断,然后连接上主sql语句,就可以针对实体的关联实体进行相应的关联操作了。/物品表的操作:$model_goods = & m(goods);$goods_info = $model_goods-find(array(conditions = “if_show=1 and closed=0,fields = goods_id,goods_name,s.store_id,s.store_name,join = blongs_to_store); 这里的join = blongs_to_store ,我们从上面的:/ 一个商品只能属于一个店铺belongs_to_store = array(model = store,type = BELONGS_TO,foreign_key = store_id,reverse = has_goods,),这里我们可以知道这是在与store表进行关联查找了。到这里,读者就可以知道,如果在上面进行二次开发的话,怎样进行数据库操作就已经很明确的了。在BaseModel与cls_mysql(mysql.php)中,有很多的有关数据操作的函数,这里就不需要再一一进行解释了,而在cls_mysql中,有一些更基础的操作函数,还有仿真 Adodb 的函数,可以直接跳过BaseModel中的函数以上介绍了如何在ecmall的平台上进行数据库操作,如果操作更加的复杂,这里还有一种更加直接的方法:$sql = “select g.goods_id,g.goods_name, from “.DB_PREFIX.”goods g, “.DB_PREFIX.”goods_spec gs , “.DB_PREFIX.”store s where cate_id=”.$cate_id.” AND g.if_show = 1 AND g.closed = 0 and g.goods_id=gs.goods_id and g.store_id=s.store_id and gs.stock0 and s.state=1 order by g.add_time desc limit 6;$goods_mod =& m(goods);$category_goods = $goods_mod-getAll($sql);if(!$category_goods)$category_goods=array();return $category_goods; 就可以直接使用sql语句进行数据操作了。还可以在BaseModel中定义自己的操作方法,其中可以使用$this-db-(cls_mysql中定义的方法) 来调用cls_mysql中的函数,从而可以添加更加复杂的数据操作函数。好了,数据操作分析就这些了,有不对之处,还请拍砖!Ecmall的详细分析3-登录用户信息$this-visitor-get(“user_id”)的实现在ecpp.base.php中定义了一个BaseVisitor extends Object 类,它对session中的当前登录的用户信息进行判断与初使化,我们先看看它的构造器:Php代码1. function BaseVisitor() 2. 3. if ($_SESSION$this-_info_keyuser_id) 4. 5. $this-info =$_SESSION$this-_info_key; 6. $this-has_login = true; 7. 8. else 9. 10. $this-info = array( 11. user_id = 0, 12. user_name = Lang:get(guest) 13. ); 14. $this-has_login = false; 15. 16. 它在构造器中就对$_SESSION中进行_info_key的判断,判断是否存在,存在则用户已经登录,不存在,则用户还没有登录而这里的_info_key,则是在它的子类:UserVisitor extends BaseVisitor中进行附值的:Php代码1. class UserVisitor extends BaseVisitor 2. 3. var $_info_key= user_info; 4. 这个子类,在FrontendApp extends ECBaseApp类中的:Php代码1. function _init_visitor() 2. 3. $this-visitor =& env(visitor, new UserVisitor(); 4. 中对visitor进行初使化的。因此这就可以让我们在FrontendApp的子类中使用$this-visitor-get(“user_id”)就可以获取

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论