19.MVC

作者: dptms | 来源:发表于2017-04-18 08:58 被阅读231次

    MVC

    代码的管理,代码级项目构架,依据代码的类型(功能),将代码分门别类的存储在不同的文件中。

    目前比较主流的管理方式,依据代码的功能,将代码分成三大类,分别用M,V,C来表示,简称为MVC项目架构思想。

    • M:model 模型
      数据业务逻辑处理,会返回处理好的数据 可以暂且理解为从数据库取出数据

    • V:view 视图
      直观的图形界面

    • c:controller 控制器
      向系统发出指令的工具和帮手

    mvc工作流程

    请求->入口->控制器->模型->视图->输出

    第一步 浏览者 调用控制器,对他发出指令

    第二步 控制器 指令选取一个合适的模型

    第三步 模型 按控制器指令取相应数据

    第四部 控制器 按指令选取相应视图

    第五步 视图 把第三步取到的数据按用户想要的样子显示出来

    必要的特点:
    浏览器仅仅会请求控制器,从控制器获取相应结果。意味着所有url地址都是请求某个c才可以

    • 模型和视图都被控制器调用

    • 模型和视图不需要完成任何的交互

    • 通常一个表对应一个模型

    前端控制器(入口文件)

    index.php,用来实例化控制器对象,并调用方法动作的文件,称之为:前端控制器,负责分发参数,也被成为请求分发器,将请求分发给某个控制器的动作执行机器。

    还被称之为入口文件,指定是只要该项目的功能,都需要经过index.php完成。

    如何使前端控制器,能够做到可以在 任意控制器类 的 任意动作 一个前端控制器就够了,所有功能都由该前端控制器来执行!

    逻辑上,区分开当前应该执行那个控制器的那个方法动作,通过请求index.php时,向其传递get参数的方式完成:

    例如:
    index.php?c=控制器&a=方法名
    

    参数哪来的?生成连接地址时,已经生成好了,浏览器用户只需要点击操作即可!额外的,通常会有默认功能,默认的控制器和默认的动作。

    将当前的控制器名 动作名,通常会选择存储在常量中的原因:

    1. 保证该次请求脚本周期内,当前的值不变。
    2. 每次请求由控制器和动作来决定执行哪个功能

    使用,凡事需要使用当前控制器名,和当前动作名的地方,都是以上定义好的常量即可

    路径

    相对路径:相对于当前位置的路径标示方式。
    核心问题:确定当前的位置

    当前位置(当前工作目录)确定,过程:
    浏览器请求web服务器,web服务器交由php核心处理php脚本,当php核心程序处理php脚本时,需要确定当前工作目录(CWD current working drectort),就是当前目录,确定原则,php核心执行的第一个执行位置
    当前工作目录,直到脚本周期结束,或者人为更改才会变更。意味着,常规的情况, 当前工作目录,永远是url请求的脚本所在路径,而不取决于,载入哪个文件。

    getcwd()获取当前工作目录。

    自定义框架

    基础代码(model,mysqldb)与功能(controller,matchmodel)相分离

    • 基础代码:所有项目都可以使用,框架代码。
    • 功能代码:具体实现当前项目某个功能的代码

    框架、功能代码分离

    例:
    app(功能代码,应用程序)
    framework(基础代码,框架代码)[工厂类,模型类,mysql数据库类]

    功能代码模块划分,module
    功能模块,也叫平台,控制器分组,指的是:功能大的集合
    例:
    前台模块和后台模块
    app目录中,划分多个模块
    home,admin,wechat,mobile,debug,alpha,meta,test
    比较特殊的 common(公共[配置,函数])

    mvc的划分

    在模块中划分model,view,controller中

    mvc框架

    例如时下比较流行的 thinkphp yii laravel

    框架:基础结构和基础代码的集合,不包含业务逻辑的实现,基础代码可以用于任何业务逻辑中。

    mvc框架:采用框架实现功能时,需要满足mvc的代码管理架构思想,则该框架九尾mvc框架。(提供一定的功能以外,还需要有基础的结构)

    m 模型层的实现

    典型的框架都会采用面向对象的思想开发
    具体的某个模型,就是某个模型的实例(对象)
    结构如下:
    每个数据库中需要操作的数据表,会对应项目中的一个模型。

    需要操作多张表的情况,在主要数据对应表中操作。

    基础模型类 model-模型对象要实现单例化-工厂模式

    c 控制器的实现

    深度使用面向对象的思想

    将一类相关的操作,封装在一个控制器中,每个操作,就是一个控制器方法,称之为动作action

    目前的做法,每个功能在一个控制器文件,例如 match_c team_c,该设计会带来控制器文件过多(增删改查),需要将相关的一系列功能,整合到一个控制器文件中

    index.php入口文件

    通常会放在项目根目录(documentroot)中,浏览器仅仅回去请求入口文件

    /根目录
    |---app/应用程序目录
        |---home/前台
            |---m/
            |---v/
            |---c/
        |---admin/后台
        |---common/公共目录
    |---framework/框架基础目录
        |---mysqlDb.class.php
        |---factory.class.php
        |---model.class.php
    index.php入口文件
    

    修改载入文件路径-保证运转

    http://localhost/index.php?module=home&controller=user&action=login&var=value
    

    直接请求,通过错误提示修改

    类文件的自动加载

    类名与类文件地址关系如下:
    其一:框架中所有的类,可以完全确定的类。框架一旦定义好了,类确定了。
    采用类名与文件位置映射表(速度快)
    其二:应用程序中app模型和控制器类,适应不同功能而变化。
    采用固定规则进行加载。
    模型类:Model结尾 在当前模块目录中存储
    控制类:Controller结尾 在当前模块下controller子目录,以类名.class.php结尾

    编码实现:

    index.php中,定义自动加载方法
    //自动加载实现
    spl_auto_register('xxx');
    $classlist = array();
    类文件地址映射表,定义在方法外没保证定义一次,以为会被调用多次
    function xxx($classname){
        //映射加载
        $classlist = $_GLBALS['classlist'];
        if(isset($classlist[$classname])){
            require $classlist[$classname]
        }elseif('Model'==substr($classname,-5)){
            require './app/'.MODULE.'/model/'.$classname.'Model.class.php';
        }elseif('Controller'==substr($classname,-10)){
            require './app/'.MODULE.'/controller/'.$classname.'Controller.class.php';
        }
    //规则加载
    }
    

    相关文章

      网友评论

          本文标题:19.MVC

          本文链接:https://www.haomeiwen.com/subject/owumittx.html