爲了未來學習成熟穩定的框架,我先找到了一個MVC微框架進行入門學習,掌握一定的理論體系,有利於加深對大框架的理解,加快吸收的速度,避免思維僵化。
一、MVC工作流程初步認識
- 瀏覽者 --> 調用控制器,對他發出指令
- 控制器 --> 按指令選取一個合適的模型
- 模型 --> 按控制器指令取相應數據
- 控制器 --> 按指令選取相應視圖
- 視圖 --> 把第三步取到的數據按用戶想要的樣子顯示出來
(一)示例:
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微型框架的實際運用
教程模板略。
自己用所學的知識做了個前臺小網站:企業管理虛擬實景實驗設計大賽網站