在ecmall.php文件中实例化控制器类,每一个控制器类,必须继承(extends)upload\admin\app\backend.base.php文件。在继承中调用方法是谁先被继承谁的方法被先调用。

以default为例,首先在公共入口文件index.php文件中包含eccore/ecmall.php文件,调用startup方法并把includes/global.lib.php,includes/libraries/time.lib.php,includes/ecapp.base.php,includes/plugin.base.php,app/backend.base.php,以数据方式传递。在ECMAall类中的startup()方法中包含了eccore/controller/app.base.php和eccore/model/model.base.php文件。

获得控制器默认为[upload\admin\app\default.app.php文件,并继承BackendApp(app/backend.base.php)类,并继承ECBaseApp(includes/ecapp.base.ph)类,并继承BaseApp(eccore/controller/app.base.php),并继承Object(eccore/ecmall.php)]。然后调用ECBaseApp中的do_action()方法在调用其实父类BaseApp中的do_action()并判断$act(index)方法在默认控制器中是否存在,如果存在并符合条件,调用本对像是最早继承文件(app/backend.base.php)他中的_run_action()方法。

01 /**
02  *    后台的需要权限验证机制
03  *
04  *    @author    Garbin
05  *    @return    void
06  */
07 function _run_action()
08 {
09     /* 先判断是否登录 */
10     if (!$this->visitor->has_login)
11     {
12         $this->login();
13  
14         return;
15     }
16  
17     /* 登录后判断是否有权限 */
18     if (!$this->visitor->i_can('do_action'$this->visitor->get('privs')))
19     {
20         $this->show_warning('no_permission');
21  
22         return;
23     }
24  
25     /* 运行 */
26     parent::_run_action();
27 }

在此要判断当前用户是否登录。

如果没有登录,调用(app/backend.base.php)他中的login()方法。

01 function login()
02 {
03     if ($this->visitor->has_login)
04     {
05         $this->show_warning('has_login');
06  
07         return;
08     }
09     if (!IS_POST)
10     {
11         if (Conf::get('captcha_status.backend'))
12         {
13             $this->assign('captcha', 1);
14         }
15         $this->display('login.html');
16     }
17     else
18     {
19         if (Conf::get('captcha_status.backend') && base64_decode($_SESSION['captcha']) !=strtolower($_POST['captcha']))
20         {
21             $this->show_warning('captcha_faild');
22  
23             return;
24         }
25  
26         $user_name = trim($_POST['user_name']);
27         $password  $_POST['password'];
28  
29         $ms =& ms();
30         $user_id $ms->user->auth($user_name$password);
31         if (!$user_id)
32         {
33             /* 未通过验证,提示错误信息 */
34             $this->show_warning($ms->user->get_error());
35  
36             return;
37         }
38  
39         /* 通过验证,执行登陆操作 */
40         if (!$this->_do_login($user_id))
41         {
42             return;
43         }
44  
45         $this->show_message('login_successed',
46             'go_to_admin''index.php');
47     }
48 }

然后调用includes/ecapp.base.php文件中的display()方法加载页面模板,在加载过程中需要给视图传递变量,调用eccore/controller/app.base.php中的assign()方法,在这个方法中还需要调用eccore/controller/app.base.php中的_init_view()方法,在这个过程中很重要因为他要引用返回eccore/ecmall.php文件中的& v()方法所引用的变量(引用eccore/view/template.php)文件,类似于加载,然后在eccore/controller/app.base.php中的assign()方法调用(eccore/view/template.php)文件assign()方法,以,键·值,形式赋值给_var数组中。

display()函数:

01 function display($f)
02 {
03     if ($this->_hook('on_display'array('display_file' => & $f)))
04     {
05         return;
06     }
07     $this->assign('site_url', SITE_URL);
08     $this->assign('ecmall_version', VERSION);
09     $this->assign('random_number', rand());
10  
11     /* 语言项 */
12     $this->assign('lang', Lang::get());
13  
14     /* 用户信息 */
15     $this->assign('visitor', isset($this->visitor) ? $this->visitor->info : array());
16  
17     /* 新消息 */
18     $this->assign('new_message', isset($this->visitor) ? $this->_get_new_message() : '');
19     $this->assign('charset', CHARSET);
20     $this->assign('price_format', Conf::get('price_format'));
21     $this->assign('async_sendmail'$this->_async_sendmail());
22     $this->_assign_query_info();
23  
24     parent::display($f);
25  
26     if ($this->_hook('end_display'array('display_file' => & $f)))
27     {
28         return;
29     }
30 }

assign()函数:

01 /**
02  *    给视图传递变量
03  *
04  *    @author    Garbin
05  *    @param     string $k
06  *    @param     mixed  $v
07  *    @return    void
08  */
09 function assign($k$v = null)
10 {
11     $this->_init_view();
12     if (is_array($k))
13     {
14         $args  = func_get_args();
15         foreach ($args as $arg)     //遍历参数
16         {
17             foreach ($arg as $key => $value)    //遍历数据并传给视图
18             {
19                 $this->_view->assign($key$value);
20             }
21         }
22     }
23     else
24     {
25         $this->_view->assign($k$v);
26     }
27 }

_init_view()函数:

01 /**
02  *    初始化视图连接
03  *
04  *    @author    Garbin
05  *    @param    none
06  *    @return    void
07  */
08 function _init_view()
09 {
10     if ($this->_view === null)
11     {
12         $this->_view =& v();
13         $this->_config_view();  //配置
14     }
15 }

在includes/ecapp.base.php文件中的display()中调用其父类eccore/controller/app.base.php中的display()方法,在display()方法中引用变量调用(eccore/view/template.php)文件中的display()方法,在display()方法中首先要判断当前的页面文件(upload\admin\templates)是否被修改如果有被修改重新缓存(upload\temp\compiled\admin),在模板缓存的时候首先要用strpos()方法判断编码头部(\xEF\xBB\xBF)是否出现过,如果出现在用我们最常用的str_replace()方法把其替换为空。

在页面提交中用到define('IS_POST', (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST'))来判断是否提交,因为在页面提交的时候,$_SERVER['REQUEST_METHOD']默认为GET。

在登录页面中用method="post"方法提交表单所以得到IS_POST定义值为TRUE,进入到执行SQL语句中,判断是否登录成功。

在这个过程中要引用includes/global.lib.php文件中的&ms()方法(此方法中包含/includes/passport.base.php,/includes/passports/' . MEMBER_TYPE . '.passport.php,MEMBER_TYPE在data/config.inc.php中定义默认为default),把变量值地址引用到/includes/passports/default.passport.php文件中DefaultPassport类,DefaultPassport(/includes/passports/default.passport.ph)继承了BasePassport(/includes/passport.base.php)

01 /**
02  *    连接会员系统
03  *
04  *    @author    Garbin
05  *    @return    Passport 会员系统连接接口
06  */
07 function &ms()
08 {
09     static $ms = null;
10     if ($ms === null)
11     {
12         include(ROOT_PATH . '/includes/passport.base.php');
13         include(ROOT_PATH . '/includes/passports/' . MEMBER_TYPE . '.passport.php');
14         $class_name  = ucfirst(MEMBER_TYPE) . 'Passport';
15         $ms new $class_name();
16     }
17  
18     return $ms;
19 }

在这个过程中,把若干类实例化,所以调用auth(&username,&password)判断用户是不是存在正确,如果正确获得用户ID执行登陆操作调用_do_login方法,在这里我们的回到刚加载文件时候的初始化中因为在includes/ecapp.base.php文件初始化的时候执行了$this->_init_visitor();方法引用了AdminVisitor他类并继承了BaseVisitor类,所以可以在_do_login()方法中应用$this->visitor->assign()方法,其实就是BaseVisitor类中的

1 function assign($user_info)
2 {
3     $_SESSION[$this->_info_key]   =   $user_info;
4 }

这样就把用户信息用SESSION保存,在执行操作的时候就可以对$this->has_login进行改变了。

好了这就是登录了。

其实他应用到"引用"和"继承"比较多所以会让初学者都感觉到很乱,没有头绪。引用就是不同的名字访问同一个变量内容,引用作为函数参数可以避免参数对象的额外拷贝。

如果程序比较大,引用同一个对象的变量比较多,并且希望用完该对象后手工清除它,个人建议用 "&" 方式,然后用$var=null的方式清除.另外, php5中对于大数组的传递,建议用 "&" 方式, 毕竟节省内存空间使用。

01 function qev(&$array)
02 {
03      Var_export($array);
04 }
05  
06 $array_qev array(
07 '1'=>'a','2'=>'b'
08 )
09  
10 Qev($array_qev);

继承其实结果就是为增加代码的可重用性,也就是你定义一个方法如果他有一定的共性可以被多个新增加的效果所调用。

如果登录,在(app/backend.base.php)他文件_run_action()他方法中调其父类includes/ecapp.base.php文件中的_run_action()方法,在调用其父类eccore/controller/app.base.php他文件中的_run_action()方法,在此方法中调用自己所在的控制器(默认default)也就是(upload\admin\app\default.app.php)文件中的方法(默认index)index();

这些只是一点程序走向结构,具体内容结构还没有研究。程序结构给人感觉似乎挺乱的,但是如果细心研究执行效果非常的好。

剖析ECMALL的登录机制的更多相关文章

  1. 分析ECMall的注册与登录机制

    ecmall的注册流程index.php?app=member&act=register. 首先app是member,act是register方法. index.php中.通过ecmall的s ...

  2. 剖析Qt的事件机制原理

    版权声明 请尊重原创作品.转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正. QT源码解析(一) QT创建窗口程序.消息循环和WinMai ...

  3. 单系统登录机制SSO

    一.单系统登录机制 1.http无状态协议 web应用采用browser/server架构,http作为通信协议.http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关 ...

  4. SSH免密登录机制

     SSH免密登录机制:(见下图) 1.A先使用ssh-keygen生成一对公钥和私钥:ssh-keygen 2.将A的公钥复制给B一份,并且将其追加到B的授权文件中:ssh-copy-id B 3.接 ...

  5. 一次实战CTF-WEB(多重登录机制中的缺陷)

    要求登录admin账号 1.登录界面 我们发现有找回密码这个易受攻击点 2.直奔找回密码 通过观察前两个阶段url(reset1.htm1 reset2.html),我们推测出了第三个阶段的url(r ...

  6. 聊一聊Axios与登录机制

    前言 因为HTTP是一个stateless的协议,服务器并不会保存任何关于状态数据. 所以需要登录功能让服务器在以后请求的过程中能够识别到你的身份,而不是每次发请求都要输入用户名和密码. 下面介绍一下 ...

  7. 深度剖析JDK动态代理机制

    摘要 相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象. 代理模式 使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过 ...

  8. Session和Cookie,Django的自动登录机制

    什么是Cookie? Cookie是浏览器的本地存储机制,存储服务器返回的各种信息,下次发起请求时再发送给服务端,比如访问baidu 什么是Session? 刚才说道,Cookie存储服务端返回的信息 ...

  9. ecmall用户登录后自动退出解决方法

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

随机推荐

  1. redhat系统安装部署

    linux 系统安装部署 1).光盘引导,选择第一项: 2)介质检查,选择skip: 3).欢迎界面,直接下一步: 4).选择安装过程使用的语言,选择“English”; 5).选择键盘布局,不需要修 ...

  2. hbuilder用自己的服务

    2016-03-10 以后写测试demo用Sublime3 http://docs.emmet.io/cheat-sheet/ 更多炫酷信息和emmet语法请参见: 视频demo 语法文档 2016- ...

  3. JS中的replace方法以及与正则表达式的结合应用

    replace方法的语法是:stringobj.replace(rgexp, replacetext) 其中stringobj是字符串(string),reexp可以是正则表达式对象(regexp)也 ...

  4. centos 6.4 安装firefox使用的flashplayer插件

    1.centos安装完后居然没flash-plugin,去官网下载居然告诉已经安装了,可是firefox又的确放不出来flash视频. 2.google一下,去官网下载个tar.gz格式文件.把lib ...

  5. Java中正确使用hashCode() 和equals() 、==

    在java编程中,经常会遇到两个对象中某个属性的比较,常常会用到的方法有: == .equals().但是两者使用起来有什么区别呢? 一.== java中的==是比较两个对象在JVM中的地址.比较好理 ...

  6. C#获取时间戳的问题

    最近在做一个接口,需要用到时间戳,在请求接口时,返回超时,接口方的技术称是时间戳的不对(超出一定范围[比如1分钟]就返回超时)导致的. 首先,看代码: public static double Get ...

  7. Dao模型设计(基于Dao与Hebernate框架)

    以前没有Dao设计模型之前,一般都是这样的流程: ①先设计实体对象 学生对象: package com.itheima.domain; import java.io.Serializable; imp ...

  8. scrapy抓取到中文,保存到json文件为unicode,如何解决.

    http://scrapy-chs.readthedocs.org/zh_CN/latest/intro/overview.html 以上链接是很好的scrapy学些资料.感谢marchtea的翻译. ...

  9. Codevs 5208 求乘方取模

    5208 求乘方取模 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 未定级 题目描述 Description 给定非负整数A.B.M,求(A ^ B) mod M. 输入描述 Inpu ...

  10. (转)IOS中获取各种文件的目录路径的方法

    iphone沙箱模型的有四个文件夹,分别是什么,永久数据存储一般放在什么位置,得到模拟器的路径的简单方式是什么. documents,tmp,app,Library. (NSHomeDirectory ...