學習筆記之mvc架構模式分析與設計

爲了未來學習成熟穩定的框架,我先找到了一個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微型框架的實際運用

教程模板略。

自己用所學的知識做了個前臺小網站:企業管理虛擬實景實驗設計大賽網站

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章