欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

学习笔记之mvc架构模式分析与设计

程序员文章站 2022-04-01 23:03:24
...

为了未来学习成熟稳定的框架,我先找到了一个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;
    }
}

运行结果:

学习笔记之mvc架构模式分析与设计


 

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

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');
    }
}

目录

学习笔记之mvc架构模式分析与设计


 

四、微框架的建立

研发的原则:

  • 业务逻辑全进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) 启动引擎程序(完成一系列初始化并调用控制器)

学习笔记之mvc架构模式分析与设计

 

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微型框架的实际运用

教程模板略。

自己用所学的知识做了个前台小网站:企业管理虚拟实景实验设计大赛网站