mvc架构模式分析与设计(慕课网学习笔记)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37431724/article/details/88604964

为了未来学习成熟稳定的框架,我先找到了一个MVC微框架进行入门学习,掌握一定的理论体系,有利于加深对大框架的理解,加快吸收的速度,避免思维僵化。


一、MVC工作流程初步认识

  1. 浏览者 --> 调用控制器,对他发出指令
  2. 控制器 --> 按指令选取一个合适的模型
  3. 模型 --> 按控制器指令取相应数据
  4. 控制器 --> 按指令选取相应视图
  5. 视图 --> 把第三步取到的数据按用户想要的样子显示出来

(一)示例:

test.php

require_once 'testController.class.php';
require_once 'testModel.class.php';
require_once 'testView.class.php';

//第一步:浏览者 --> 调用控制器,对他发出指令
$testController = new testController();
$testController -> show();

testController.class.php
class testController{
    function show(){
//      第二步:控制器 --> 按指令选取一个合适的模型
        $testModel = new testModel();
        $data = $testModel->get();

//      第四步:控制器 --> 按指令选取相应视图
        $testView = new testView();
        $testView->display($data);
    }
}

testModel.class.php

class testModel{
//  第三步:模型 --> 按控制器指令取相应数据
    function get(){
        return "MVC工作流程初步认识";
    }
}

testView.class.php

class testView{
//  第五步:视图 --> 把第三步取到的数据按用户想要的样子显示出来
    function display($data){
        echo $data;
    }
}

运行结果:


 

二、简易调用实例化及入口文件

function.php

function C($name, $method){
    require_once '/libs/Controller/'.$name.'Controller.class.php';
    $controller = $name.'Controller';
    $obj = new $controller();
    $obj -> $method();
}

//模型的方法不带有自己的参数,所以不引入method会灵活一些。控制器引入method是因为它是不允许有自己的参数的。
function M($name){
    require_once('/libs/Model/'.$name.'Model.class.php');
    $model = $name.'Model';
    $obj = new $model();
    return $obj;
}

function V($name){
    require_once('/libs/View/'.$name.'View.class.php');
    $view = $name.'View';
    $obj = new $view();
    return $obj;
}

//对非法字符进行转义
function daddslashes($str){
    return (!get_magic_quotes_gpc())?addslashes($str):$str;
}

testController.class.php
class testController{
    function show(){
//      第二步:控制器 --> 按指令选取一个合适的模型
        $testModel = M('test');
        $data = $testModel -> get();

//      第四步:控制器 --> 按指令选取相应视图
        $testView = V('test');
        $testView -> display($data);
    }
}

 

入口程序:在网上经常被称为单一入口机制,单一入口指在一个web应用程序中,所有的请求都是指向一个脚本文件。

index.php

//1. 统一入口文件为首的url形式:index.php?controler=控制器名&method=方法名
require_once 'function.php';

//2. 在入口文件里使用安全的方式就收传递来的控制器名和方法名

//设置允许访问的控制器名与方法名
$controllerAllow = array('test','index');
$methodAllow = array('test','index','show');

//使用daddslashes对_GET传递进来的参数进行非法参数过滤,用in_array判断传入的控制器与方法名是否允许进入。
$controller=in_array($_GET['controller'],$controllerAllow)?daddslashes($_GET['controller']):'index';
$method=in_array($_GET['method'],$methodAllow)?daddslashes($_GET['method']):'index';

C($controller, $method);

 

三、第三方类调用

function.php

//第三方类调用函数
function ORG($path, $name, $params=array()){
    // path 是路径,name是第三方类名,params 是该类初始化的时候需要指定、赋值的属性集合,格式为 array(属性名=>属性值, 属性名2=>属性值2……)
    require_once('libs/ORG/'.$path.$name.'.class.php');
    $obj = new $name();
    if(!empty($params)){
        foreach($params as $key=>$value){
            $obj->$key = $value;
        }
    }
    return $obj;
}

index.php

//smarty实例化
$view = ORG('Smarty/', 'Smarty', $viewconfig);

config.php

//对smarty属性进行初始化
$viewconfig = array('left_delimiter' => '{', 'right_delimiter' => '}', 'template_dir' => 'tpl', 'compile_dir' => 'template_c', 'cache_dir' => 'cache');

testController.class.php

class testController{
    function show(){
        global $view;
//      第二步:控制器 --> 按指令选取一个合适的模型
//        $testModel = new testModel();
        $testModel = M('test');
        $data = $testModel -> get();

//      第四步:控制器 --> 按指令选取相应视图
//        $testView = new testView();
//        $testView = V('test');
//        $testView -> display($data);
        $view->assign('username', "用户名");
        $view->display('test.tpl');
    }
}

目录


四、微框架的建立

研发的原则:

  • 业务逻辑全进model层
  • 大事化小,分而治之
  • 相似功能合二为一

(一)简单工厂模式

用工厂方法代替new操作的一种模式。可以统一管理对象的实例化,便于扩展维护。

DB工厂类 DB.class.php

class DB {//类名在php里面是一个全局变量,DB::$db或DB::方法()直接调用

    public static $db;//用于保存实例化对象

    public static function init($dbtype, $config) {
        self::$db = new $dbtype;
        self::$db->connect($config);
    }

    public static function query($sql){
        return self::$db->query($sql);
    }

    public static function findAll($sql){
        $query = self::$db->query($sql);
        return self::$db->findAll($query);
    }

    public static function findOne($sql){
        $query = self::$db->query($sql);
        return self::$db->findOne($query);
    }

    public static function findResult($sql, $row = 0, $filed = 0){
        $query = self::$db->query($sql);
        return self::$db->findResult($query, $row, $filed);
    }

    public static function insert($table,$arr){
        return self::$db->insert($table,$arr);
    }

    public static function update($table, $arr, $where){
        return self::$db->update($table, $arr, $where);
    }

    public static function del($table,$where){
        return self::$db->del($table,$where);
    }
}

视图引擎工厂类:VIEW.class.php

class VIEW {

    public static $view;

    public static function init($viewtype,$config){
        self::$view = new $viewtype;
//        对试图引擎类进行初始化
        /*$smarty = new Smarty();//实例化smarty
        $smarty->left_delimiter=$config["left_delimiter"];//左定界符
        $smarty->right_delimiter=$config["right_delimiter"];//右定界符
        $smarty->template_dir=$config["template_dir"];//html模板的地址
        $smarty->compile_dir=$config["compile_dir"];//模板编译生成的文件
        $smarty->cache_dir=$config["cache_dir"];//缓存*/
        foreach($config as $key=>$value){
            self::$view -> $key = $value;
        }

    }

    public static function assign($data){
        foreach($data as $key=>$value){
            self::$view->assign($key, $value);
        }
    }

    public static function display($template){
        self::$view->display($template);
    }
}

(二)操作Mysql类

<?php
class mysql{

	/**
	 * 报错函数
	 * 
	 * @param string $error
	 */
	function err($error){
		die("对不起,您的操作有误,错误原因为:".$error);//die有两种作用 输出 和 终止   相当于  echo 和 exit 的组合
	}

	/**
	 * 连接数据库
	 * 
	 * @param string $dbhost 主机名
	 * @param string $dbuser 用户名
	 * @param string $dbpsw  密码
	 * @param string $dbname 数据库名
	 * @param string $dbcharset 字符集/编码
	 * @return bool  连接成功或不成功 
	 **/
	function connect($config){
		extract($config);
		if(!($con = mysql_connect($dbhost,$dbuser,$dbpsw))){//mysql_connect连接数据库函数
			$this->err(mysql_error());
		}
		if(!mysql_select_db($dbname,$con)){//mysql_select_db选择库的函数
			$this->err(mysql_error());
		}
		mysql_query("set names ".$dbcharset);//使用mysql_query 设置编码  格式:mysql_query("set names utf8")
	}
	/**
	 * 执行sql语句
	 *
	 * @param string $sql
	 * @return bool 返回执行成功、资源或执行失败
	 */
	function query($sql){
		if(!($query = mysql_query($sql))){//使用mysql_query函数执行sql语句
			$this->err($sql."<br />".mysql_error());//mysql_error 报错
		}else{
			return $query;
		}
	}

	/**
	*列表
	*
	*@param source $query sql语句通过mysql_query 执行出来的资源
	*@return array   返回列表数组
	**/
	function findAll($query){
		while($rs=mysql_fetch_array($query, MYSQL_ASSOC)){//mysql_fetch_array函数把资源转换为数组,一次转换出一行出来
			$list[]=$rs;
		}
		return isset($list)?$list:"";
	}

	/**
	*单条
	*
	*@param source $query sql语句通过mysql_query执行出的来的资源
	*return array   返回单条信息数组
	**/
	function findOne($query){
		$rs = mysql_fetch_array($query, MYSQL_ASSOC);
		return $rs;
	}

	/**
	*指定行的指定字段的值
	*
	*@param source $query sql语句通过mysql_query执行出的来的资源
	*return array   返回指定行的指定字段的值
	**/
	function findResult($query, $row = 0, $filed = 0){
		$rs = mysql_result($query,  $row, $filed);
		return $rs;
	}

	/**
	 * 添加函数
	 *
	 * @param string $table 表名
	 * @param array $arr 添加数组(包含字段和值的一维数组)
	 * 
	 */
	function insert($table,$arr){
		//$sql = "insert into 表名(多个字段) values(多个值)";
		foreach($arr as $key=>$value){//foreach循环数组
			$value = mysql_real_escape_string($value);
			$keyArr[] = "`".$key."`";//把$arr数组当中的键名保存到$keyArr数组当中
			$valueArr[] = "'".$value."'";//把$arr数组当中的键值保存到$valueArr当中,因为值多为字符串,而sql语句里面insert当中如果值是字符串的话要加单引号,所以这个地方要加上单引号
		}
		$keys = implode(",",$keyArr);//implode函数是把数组组合成字符串 implode(分隔符,数组)
		$values = implode(",",$valueArr);
		$sql = "insert into ".$table."(".$keys.") values(".$values.")";//sql的插入语句  格式:insert into 表(多个字段)values(多个值)
		$this->query($sql);//调用类自身的query(执行)方法执行这条sql语句  注:$this指代自身
		return mysql_insert_id();
	}

	/**
	*修改函数
	*
	*@param string $table 表名
	*@param array $arr 修改数组(包含字段和值的一维数组)
	*@param string $where  条件
	**/
	function update($table,$arr,$where){
		//update 表名 set 字段=字段值 where ……
		foreach($arr as $key=>$value){
			$value = mysql_real_escape_string($value);
			$keyAndvalueArr[] = "`".$key."`='".$value."'";
		}
		$keyAndvalues = implode(",",$keyAndvalueArr);
		$sql = "update ".$table." set ".$keyAndvalues." where ".$where;//修改操作 格式 update 表名 set 字段=值 where 条件
		$this->query($sql);
	}

	/**
	*删除函数
	*
	*@param string $table 表名
	*@param string $where 条件
	**/
	function del($table,$where){
		$sql = "delete from ".$table." where ".$where;//删除sql语句 格式:delete from 表名 where 条件
		$this->query($sql);
	}

}

(三)微型框架编写

1.框架组织结构

(1) 函数库

(2) 类库

    a. 视图引擎库

    b. DB引擎库

    c. 核心库

(3) require文件清单

(4) 启动引擎程序(完成一系列初始化并调用控制器)

 

2.文件清单:include.list.php

//罗列清单程序
$paths = array(
    'function/function.php',
    'libs/core/DB.class.php',
    'libs/core/VIEW.class.php',
    'libs/db/mysql.class.php',
    'libs/view/Smarty/Smarty.class.php'
);

3.引擎程序:PC.php

//启动引擎程序

//引入清单文件
$currentdir = dirname(__FILE__);//获取当前文件所在地址
include_once($currentdir.'/include.list.php');
foreach($paths as $path){
    include_once($currentdir.'/'.$path);
}

class PC{
    public static $controller;
    public static $method;
    private static $config;
    private static function init_db(){
        DB::init('mysql', self::$config['dbconfig']);
    }
    private static function init_view(){
        VIEW::init('Smarty', self::$config['viewconfig']);
    }
    private static function init_controller(){
        self::$controller = isset($_GET['controller'])?daddslashes($_GET['controller']):'index';
    }
    private static function init_method(){
        self::$method = isset($_GET['method'])?daddslashes($_GET['method']):'index';
    }
    public static function run($config){
//      1. 完成一系列初始化
        self::$config = $config;
        self::init_db();
        self::init_view();
        self::init_controller();
        self::init_method();

//      2. 调用控制器
        C(self::$controller, self::$method);
    }
}

(四)入口文件与配置文件改进

1. 入口文件:

(1) 调用配置文件

(2) 调用微型框架

(3) 启动框架引擎

 

2. 配置文件:

(1) 数据库配置信息

(2) 视图引擎配置信息

 

admin.php

/*
 入口文件
*/

header("Content-type: text/html; charset=utf-8");

//(1)调用配置文件
require_once('config.php');
//(2)调用微型框架
require_once('framework/pc.php');
//(3)启动框架引擎
PC::run($config);

 

config.php

/*
 配置文件
*/
$config = array(
    //视图引擎配置信息:对smarty属性进行初始化
    'viewconfig' => array(
        'left_delimiter' => '{',  'right_delimiter' => '}',  'template_dir' => 'tpl',  'compile_dir' => 'data/template_c'),

    //数据库配置信息:对mysql属性进行初始化
    'dbconfig' => array(
        'dbhost' => 'localhost', 'dbuser'=>'root', 'dbpsw' => '0330' , 'dbname' => 'newsreport', 'dbcharset' => 'utf8')
);

 

五、MVC微型框架的实际运用

过程略

猜你喜欢

转载自blog.csdn.net/qq_37431724/article/details/88604964