日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

PHP核心之MVC设计模式

發(fā)布時(shí)間:2023/12/19 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 PHP核心之MVC设计模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MVC設(shè)計(jì)模式

MVC概述

MVC介紹

MVC是一個(gè)編程思想,是一種設(shè)計(jì)模式
思想:將一個(gè)功能分解成3個(gè)部分

Model(模型):處理與數(shù)據(jù)有關(guān)的邏輯
View(視圖):顯示頁(yè)面
Controller(控制器):處理業(yè)務(wù)邏輯

控制器用來(lái)接收請(qǐng)求
以后不能直接請(qǐng)求模型和視圖

MVC演化

顯示商品

# index.php
<?php
//自動(dòng)加載類
spl_autoload_register(function($class_name){
	require "./{$class_name}.class.php";
});
//連接數(shù)據(jù)庫(kù)
$param=array(
	'user'	=>	'root',
    'pwd'	=>	'',
    'dbname' => 'data'
);
$mypdo= MyPDO::getInstance($param);
//獲取商品數(shù)據(jù)
$list=$mypdo->fetchAll('select * from products');
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> <th>名稱</th> <th>價(jià)格</th> <th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>

演化一:分離視圖

# index.php
<?php
//自動(dòng)加載類
spl_autoload_register(function($class_name){
	require "./{$class_name}.class.php";
});
//連接數(shù)據(jù)庫(kù)
$param=array(
	'user'	=>	'root',
    'pwd'	=>	'',
    'dbname' => 'data'
);
$mypdo= MyPDO::getInstance($param);
//獲取商品數(shù)據(jù)
$list=$mypdo->fetchAll('select * from products');
require './products_list.html';
?>
# products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> <th>名稱</th> <th>價(jià)格</th> <th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>

演化二:分離模型

模型的規(guī)則

一個(gè)表對(duì)應(yīng)一個(gè)模型,表名和模型名必須一致
模型以Model結(jié)尾(不是必須的)

# index.php
<?php
//自動(dòng)加載類
spl_autoload_register(function($class_name){
	require "./{$class_name}.class.php";
});
// 實(shí)例化數(shù)據(jù)模型
$model= new ProductsModel();
$list= $model->getList();
// 加載視圖
require './products_list.html';
?>
# products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> <th>名稱</th> <th>價(jià)格</th> <th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>
# ProductsModel.class.php
<?php
//products模型用來(lái)操作products表
class ProductsModel {
    // 獲取products表的數(shù)據(jù)
    public function getList(){
        // 連接數(shù)據(jù)庫(kù)
        $param= array(
            'user' => 'root',
            'pwd' => '',
            'dbname' => 'data'
        );
        $mypdo= MyPDO::getInstance($param);
        // 獲取商品數(shù)據(jù)
        return $mypdo->fetchAll('select * from products');
    }
}
?>

演化三:分離基礎(chǔ)模型

概念

連接數(shù)據(jù)庫(kù)的代碼每個(gè)模型都要使用
所有我們需要將連接數(shù)據(jù)庫(kù)的代碼封裝到基礎(chǔ)模型類中(Model)

# index.php
<?php
//自動(dòng)加載類
spl_autoload_register(function($class_name){
	require "./{$class_name}.class.php";
});
// 實(shí)例化數(shù)據(jù)模型
$model= new ProductsModel();
$list= $model->getList();
// 加載視圖
require './products_list.html';
?>
# products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> <th>名稱</th> <th>價(jià)格</th> <th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>
# Model.class.php
<?php
// 基礎(chǔ)模型
class Model {
    protected $mypdo;
    public function __construct(){
        $this->initMyPDO();
    }
    // 連接數(shù)據(jù)庫(kù)
    private function initMyPDO(){
        $param= array(
            'user' => 'root',
            'pwd' => '',
            'dbname' => 'data'
        );
        $this->mypdo= MyPDO::getInstance($param);
    }
}
?>
# ProductsModel.class.php
<?php
//products模型用來(lái)操作products表
class ProductsModel extends Model{
    // 獲取products表的數(shù)據(jù)
    public function getList(){
        // 獲取商品數(shù)據(jù)
        return $this->mypdo->fetchAll('select * from products');
    }
}
?>

演化四:分離控制器

概念

控制器代碼放在index.php頁(yè)面中是不合理的
因?yàn)轫?xiàng)目中的控制器會(huì)很多,而index.php只有一個(gè)
所以需要將控制器分離開(kāi)來(lái)

控制器的規(guī)則

一個(gè)模塊必須對(duì)應(yīng)一個(gè)控制器
控制器以Controller結(jié)尾(不是必須的)
控制器中的方法以Action結(jié)尾(不是必須的)

目的防止方法名是PHP關(guān)鍵字

請(qǐng)求分發(fā)

每次請(qǐng)求都要從index.php進(jìn)入,所以index.php又叫入口文件
通過(guò)在url地址上傳遞參數(shù)來(lái)尋址

c 控制器
a 方法

# index.php
<?php
//自動(dòng)加載類
spl_autoload_register(function($class_name){
	require "./{$class_name}.class.php";
});
//確定路由
$c= $_GET['c']??'Products';   		//控制器
$a= $_GET['a']??'list';				//方法
$c= ucfirst(strtolower($c));		//首字母大寫(xiě)
$a= strtolower($a);					//轉(zhuǎn)成小寫(xiě)
$controller_name= $c.'Controller';	//拼接控制器類名
$action_name= $a.'Action';			//拼接方法名
//請(qǐng)求分發(fā)
$obj= new $controller_name();
$obj->$action_name();
?>
# products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> <th>名稱</th> <th>價(jià)格</th> <th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>
# Model.class.php
<?php
// 基礎(chǔ)模型
class Model {
    protected $mypdo;
    public function __construct(){
        $this->initMyPDO();
    }
    // 連接數(shù)據(jù)庫(kù)
    private function initMyPDO(){
        $param= array(
            'user' => 'root',
            'pwd' => '',
            'dbname' => 'data'
        );
        $this->mypdo= MyPDO::getInstance($param);
    }
}
?>
# ProductsModel.class.php
<?php
//products模型用來(lái)操作products表
class ProductsModel extends Model{
    // 獲取products表的數(shù)據(jù)
    public function getList(){
        // 獲取商品數(shù)據(jù)
        return $this->mypdo->fetchAll('select * from products');
    }
}
?>
# ProductsController.class.php
<?php
// 商品模塊
class ProductsController {
    // 獲取商品列表
    public function listAction(){
        // 實(shí)例化數(shù)據(jù)模型
        $model= new ProductsModel();
        $list= $model->getList();
        // 加載視圖
        require './products_list.html';
    }
}
?>

刪除商品

# index.php
<?php
//自動(dòng)加載類
spl_autoload_register(function($class_name){
	require "./{$class_name}.class.php";
});
//確定路由
$c= $_GET['c']??'Products';   		//控制器
$a= $_GET['a']??'list';				//方法
$c= ucfirst(strtolower($c));		//首字母大寫(xiě)
$a= strtolower($a);					//轉(zhuǎn)成小寫(xiě)
$controller_name= $c.'Controller';	//拼接控制器類名
$action_name= $a.'Action';			//拼接方法名
//請(qǐng)求分發(fā)
$obj= new $controller_name();
$obj->$action_name();
?>
# products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> 
			<th>名稱</th> 
			<th>價(jià)格</th> 
			<th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="index.php?c=Products&a=del&proid=<?=$rows['proID']?>" onclick="return confirm('確定要?jiǎng)h除嗎')">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>
# ProductsController.class.php
<?php
// 商品模塊
class ProductsController {
    // 獲取商品列表
    public function listAction(){
        // 實(shí)例化數(shù)據(jù)模型
        $model= new ProductsModel();
        $list= $model->getList();
        // 加載視圖
        require './products_list.html';
    }
    public function delAction(){
        $id= (int)$_GET['proid'];
        $model= new ProductsModel();
        if($model->del($id)){
            header('location:index.php?c=Products&a=list');
        }else{
            echo '刪除失?。?;
            exit;
        }
    }
}
?>
# ProductsModel.class.php
<?php
//products模型用來(lái)操作products表
class ProductsModel extends Model{
    // 獲取products表的數(shù)據(jù)
    public function getList(){
        // 獲取商品數(shù)據(jù)
        return $this->mypdo->fetchAll('select * from products');
    }
    // 刪除products表的數(shù)據(jù)
    public function del($proid){
        // 刪除商品數(shù)據(jù)
        return $this->mypdo->exec("delete from products where proID={$proid}");
    }
}
?>

框架目錄

創(chuàng)建目錄結(jié)構(gòu)

Application 應(yīng)用程序

Config 配置文件
Controller 控制器

Admin 后臺(tái)控制器
Home 前臺(tái)控制器

Model 模型
View 視圖

Admin 后臺(tái)視圖
Home 前臺(tái)視圖

Framework 框架

Core 核心
Lib 擴(kuò)展

Public 靜態(tài)資源

Traits 復(fù)用代碼

文件分類存放

概念

由于每次都請(qǐng)求入口文件,所以”.“表示入口文件所在的目錄

Application

Config

config.php

Controller

Admin

ProductsController.class.php

Home

Model

ProductsModel.class.php

View

Admin

products_list.html

Home

Framework

Core

Framework.class.php
Model.class.php
MyPDO.class.php

Lib

Public

images

error.fw.png
success.fw.png

Traits

Jump.class.php

index.php

添加命名空間

概念

通過(guò)文件目錄地址做命名空間
這樣獲取了命名空間就能知道文件存放的地址

# Model.class.php
<?php
namespace Core;
class Model {
    ...
}
?>
# MyPDO.class.php
<?php
namespace Core;
class MyPDO {
    ...
}
?>
# ProductsModel.class.php
<?php
namespace Model;
class ProductsModel extends Model {
    ...
}
?>
# ProductsController.class.php
<?php
namespace ControllerAdmin;
class ProductsController {
    ...
}
?>

框架類實(shí)現(xiàn)

定義路徑常量

概念

由于文件路徑使用頻率很高,而且路徑比較長(zhǎng)
所以將固定不變的路徑定義成路徑常量

知識(shí)點(diǎn)

getcwd() 入口文件的絕對(duì)路徑
windows下默認(rèn)的目錄分隔符是,Linux下默認(rèn)的目錄分隔符是/
DIRECTORY_SEPARATOR常量根據(jù)不同的操作系統(tǒng)返回不同的目錄分隔符

# Framework.class.php
private static function initConst(){
    define('DS', DIRECTORY_SEPARATOR);  //定義目錄分隔符
    define('ROOT_PATH', getcwd().DS);  //入口文件所在的目錄
    define('APP_PATH', ROOT_PATH.'Application'.DS);   //application目錄
    define('CONFIG_PATH', APP_PATH.'Config'.DS);
    define('CONTROLLER_PATH', APP_PATH.'Controller'.DS);
    define('MODEL_PATH', APP_PATH.'Model'.DS);
    define('VIEW_PATH', APP_PATH.'View'.DS);
    define('FRAMEWORK_PATH', ROOT_PATH.'Framework'.DS);
    define('CORE_PATH', FRAMEWORK_PATH.'Core'.DS);
    define('LIB_PATH', FRAMEWORK_PATH.'Lib'.DS);
    define('TRAITS_PATH', ROOT_PATH.'Traits'.DS);
}

引入配置文件

概述

在PHP7.0之前,常量不能保存數(shù)組和對(duì)象

# config.php
return array(
    //數(shù)據(jù)庫(kù)配置
    'database'=>array(),
    //應(yīng)用程序配置
    'app'=>array(
        'dp' => 'Admin',        //默認(rèn)平臺(tái)
        'dc' => 'Products',     //默認(rèn)控制器
        'da' => 'list'          //默認(rèn)方法
    )
);
# Framework.class.php
private static function initConfig(){
    $GLOBALS['config']= require CONFIG_PATH.'config.php';
}

確定路由

概述

p 平臺(tái)[platform]
c 控制器[controller]
a 方法[action]

# Framework.class.php
private static function initRoutes(){
    $p= $_GET['p']??$GLOBALS['config']['app']['dp'];
    $c= $_GET['c']??$GLOBALS['config']['app']['dc'];
    $a= $_GET['a']??$GLOBALS['config']['app']['da'];
    $p= ucfirst(strtolower($p));
    $c= ucfirst(strtolower($c));		
    $a= strtolower($a);			
    define('PLATFROM_NAME', $p);    //平臺(tái)名常量
    define('CONTROLLER_NAME', $c);  //控制器名常量
    define('ACTION_NAME', $a);      //方法名常量
    define('__URL__', CONTROLLER_PATH.$p.DS);   //當(dāng)前請(qǐng)求控制器的目錄地址
    define('__VIEW__',VIEW_PATH.$p.DS);     //當(dāng)前視圖的目錄地址
}

自動(dòng)加載類

# Framework.class.php
private static function initAutoLoad(){
    spl_autoload_register(function($class_name){
        $namespace= dirname($class_name);   //命名空間
        $class_name= basename($class_name); //類名
        if(in_array($namespace, array('Core','Lib')))   //命名空間在Core和Lib下
            $path= FRAMEWORK_PATH.$namespace.DS.$class_name.'.class.php';
        elseif($namespace=='Model')     //文件在Model下
            $path=MODEL_PATH.$class_name.'.class.php';
        elseif($namespace=='Traits')    //文件在Traits下
            $path=TRAITS_PATH.$class_name.'.class.php';
        else   //控制器
            $path=CONTROLLER_PATH.PLATFROM_NAME.DS.$class_name.'.class.php'; 
        if(file_exists($path) && is_file($path))
            require $path;
    });
}

請(qǐng)求分發(fā)

# Framework.class.php
private static function initDispatch(){
    $controller_name='Controller\'.PLATFROM_NAME.'\'.CONTROLLER_NAME.'Controller';	//拼接控制器類名
    $action_name=ACTION_NAME.'Action';	//拼接方法名
    $obj=new $controller_name();
    $obj->$action_name();
} 

封裝run()方法

# Framework.class.php
class Framework{
    //啟動(dòng)框架
    public static function run(){
        self::initConst();
        self::initConfig();
        self::initRoutes();
        self::initAutoLoad();
        self::initDispatch();
    }
}

在入口中調(diào)用run()方法

概述

run()方法調(diào)用后就啟動(dòng)了框架

# index.php
<?php
require './Framework/Core/Framework.class.php';
Framework::run();
?>

SQL方法封裝

生成insert語(yǔ)句

知識(shí)點(diǎn)

array_keys($arr) 返回?cái)?shù)組的鍵
array_values($arr) 返回?cái)?shù)組的值
array_map(fun(), $arr) 將函數(shù)作用到數(shù)組中的每個(gè)值上,并返回帶有新值的數(shù)組

$table= 'products';	//表名
//插入的數(shù)據(jù)
$data['proid']='007';
$data['proname']='鋼筆';
$data['proprice']=120;
//第一步:拼接字段名
$keys=array_keys($data);		//獲取所有的字段名
$keys=array_map(function($key){	//在所有的字段名上添加反引號(hào)
	return "`{$key}`";
},$keys);
$keys=implode(',',$keys);		//字段名用逗號(hào)連接起來(lái)
//第二步:拼接值
$values=array_values($data);	//獲取所有的值
$values=array_map(function($value){	//所有的值上添加單引號(hào)
	return "'{$value}'";
},$values);
$values=implode(',',$values);	//值通過(guò)逗號(hào)連接起來(lái)
//第三步:拼接SQL語(yǔ)句
echo $sql="insert into `{$table}` ($keys) values ($values)";

生成更新語(yǔ)句

知識(shí)點(diǎn)

array_search(value, $arr) 在數(shù)組中搜索某個(gè)鍵值,并返回對(duì)應(yīng)的鍵名

$table='products';	                //表名
$data['proname']='鋼筆';
$data['proprice']=120;
$data['proID']='111';
//獲取主鍵
function getPrimaryKey($table) {
	//連接數(shù)據(jù)庫(kù)
	$link=mysqli_connect('localhost','root','root','data');
	mysqli_set_charset($link,'utf8');
	//查看表結(jié)構(gòu)
	$rs=mysqli_query($link,"desc `{$table}`");
	//循環(huán)判斷主鍵
	while($rows=mysqli_fetch_assoc($rs)){
		if($rows['Key']=='PRI')
			return $rows['Field'];
	}
}
//第一步:獲取非主鍵
$keys=array_keys($data);	    //獲取所有鍵
$pk=getPrimaryKey($table);	    //獲取主鍵
$index=array_search($pk,$keys);	//返回主鍵在數(shù)組中的下標(biāo)
unset($keys[$index]);		    //刪除主鍵
//第二步:拼接`鍵`='值'的形式
$keys=array_map(function($key) use ($data){
	return "`{$key}`='{$data[$key]}'";
},$keys);
$keys=implode(',',$keys);
//第三步:拼接SQL語(yǔ)句
echo $sql="update `{$table}` set $keys where $pk='{$data[$pk]}'";

生成select語(yǔ)句

知識(shí)點(diǎn)

is_array($arr) 判斷變量是否為數(shù)組

function select($table,$cond=array()) {
	$sql="select * from `{$table}` where 1";
	//拼接條件
	if(!empty($cond)){
		foreach($cond as $k=>$v){
			if(is_array($v)){	        //條件的值是數(shù)組類型
				switch($v[0]){	        //$v[0]保存的是符號(hào),$v[1]是值
					case 'eq':		    //等于  equal
						$op='=';
						break;
					case 'gt':		    //大于  greater than
						$op='>';
						break;
					case 'lt':
						$op='<';
						break;
					case 'gte':
					case 'egt':
						$op='>=';
						break;
					case 'lte':
					case 'elt':
						$op='<=';
						break;
					case 'neq':
						$op='<>';
						break;
				}
				$sql.=" and `$k` $op '$v[1]'";
			}else{
				$sql.=" and `$k`='$v'";
			}
		}
	}
	return $sql;
}
//測(cè)試
$table='products';	//表名
$cond=array(
	'proname'	=>	'鋼筆',
	'proprice'	=>	array('eq','12'),
	'aa'	=>	array('gt',10),
	'bb'	=>	array('lt',20),
);
echo select($table),'<br>';
echo select($table,$cond);

獲取表名

知識(shí)點(diǎn)

get_class($this) 返回實(shí)例對(duì)象的類(包括命名空間)
basename($path) 返回路徑中的文件名部分
substr($str, startNum, endNum) 截取字符串

class Model {
	private $table;
	public function __construct($table='') {
		if($table!='')		//直接給基礎(chǔ)模型傳遞表名
			$this->table=$table;
		else {				//實(shí)例化子類模型
			$this->table=substr(basename(get_class($this)),0,-5);
		}
		echo $this->table,'<br>';
	}
}

在項(xiàng)目中封裝萬(wàn)能的增、刪、改、查

概念

由于封裝的方法可以操作所有的表
可以將這些方法封裝在基礎(chǔ)模型中

<?php
namespace Core;
//基礎(chǔ)模型
class Model {
    protected $mypdo;
    private $table; //表名
    private $pk;    //主鍵
    public function __construct($table=''){
        $this->initMyPDO();
        $this->initTable($table);
        $this->getPrimaryKey();
    }
    //連接數(shù)據(jù)庫(kù)
    private function initMyPDO() {
        $this->mypdo= MyPDO::getInstance($GLOBALS['config']['database']);
    }
    //獲取表名
    private function initTable($table){
        if($table!='')		//直接給基礎(chǔ)模型傳遞表名
            $this->table=$table;
        else {				//實(shí)例化子類模型
            $this->table=substr(basename(get_class($this)),0,-5);
        }
    }
    //獲取主鍵
    private function getPrimaryKey() {
        $rs=$this->mypdo->fetchAll("desc `{$this->table}`");
        foreach($rs as $rows){
            if($rows['Key']=='PRI'){
                $this->pk=$rows['Field'];
                break;
            }
        }
    }
    //萬(wàn)能的插入
    public function insert($data){
        $keys=array_keys($data);		//獲取所有的字段名
        $keys=array_map(function($key){	//在所有的字段名上添加反引號(hào)
                return "`{$key}`";
        },$keys);
        $keys=implode(',',$keys);		//字段名用逗號(hào)連接起來(lái)
        $values=array_values($data);	//獲取所有的值
        $values=array_map(function($value){	//所有的值上添加單引號(hào)
                return "'{$value}'";
        },$values);
        $values=implode(',',$values);	//值通過(guò)逗號(hào)連接起來(lái)
        $sql="insert into `{$this->table}` ($keys) values ($values)";
        return $this->mypdo->exec($sql);
    }
    //萬(wàn)能的更新
    public function update($data){
        $keys=array_keys($data);	//獲取所有鍵
        $index=array_search($this->pk,$keys);	//返回主鍵在數(shù)組中的下標(biāo)
        unset($keys[$index]);		//刪除主鍵
        $keys=array_map(function($key) use ($data){
                return "`{$key}`='{$data[$key]}'";
        },$keys);
        $keys=implode(',',$keys);
        $sql="update `{$this->table}` set $keys where $this->pk='{$data[$this->pk]}'";
        return $this->mypdo->exec($sql);
    }
    //刪除
    public function delete($id){
        $sql="delete from `{$this->table}` where `{$this->pk}`='$id'";
        return $this->mypdo->exec($sql);
    }
    //查詢,返回二維數(shù)組
    public function select($cond=array()){
        $sql="select * from `{$this->table}` where 1";
        if(!empty($cond)){
            foreach($cond as $k=>$v){
                if(is_array($v)){	        //條件的值是數(shù)組類型
                    switch($v[0]){	    //$v[0]保存的是符號(hào),$v[1]是值
                        case 'eq':		//等于  equal
                            $op='=';
                            break;
                        case 'gt':		//大于  greater than
                            $op='>';
                            break;
                        case 'lt':
                            $op='<';
                            break;
                        case 'gte':
                        case 'egt':
                            $op='>=';
                            break;
                        case 'lte':
                        case 'elt':
                            $op='<=';
                            break;
                        case 'neq':
                            $op='<>';
                            break;
                    }
                    $sql.=" and `$k` $op '$v[1]'";
                }else{
                    $sql.=" and `$k`='$v'";
                }
            }
        }
        return $this->mypdo->fetchAll($sql);
    }
    //查詢,返回一維數(shù)組
    public function find($id){
        $sql="select * from `{$this->table}` where `{$this->pk}`='$id'";
        return $this->mypdo->fetchRow($sql);
    }
}
?>

MVC框架代碼

入口文件

# index.php
<?php
require './Framework/Core/Framework.class.php';
Framework::run();
?>

框架文件

# Framework/Core/Framework.class.php
<?php
class Framework{
    //啟動(dòng)框架
    public static function run(){
        self::initConst();
        self::initConfig();
        self::initRoutes();
        self::initAutoLoad();
        self::initDispatch();
    }
    //定義路徑常量
    private static function initConst(){
        define('DS', DIRECTORY_SEPARATOR);  //定義目錄分隔符
        define('ROOT_PATH', getcwd().DS);  //入口文件所在的目錄
        define('APP_PATH', ROOT_PATH.'Application'.DS);   //application目錄
        define('CONFIG_PATH', APP_PATH.'Config'.DS);
        define('CONTROLLER_PATH', APP_PATH.'Controller'.DS);
        define('MODEL_PATH', APP_PATH.'Model'.DS);
        define('VIEW_PATH', APP_PATH.'View'.DS);
        define('FRAMEWORK_PATH', ROOT_PATH.'Framework'.DS);
        define('CORE_PATH', FRAMEWORK_PATH.'Core'.DS);
        define('LIB_PATH', FRAMEWORK_PATH.'Lib'.DS);
        define('TRAITS_PATH', ROOT_PATH.'Traits'.DS);
    }
    //引入配置文件
    private static function initConfig(){
       $GLOBALS['config']=require CONFIG_PATH.'config.php';
    }
    //確定路由
    private static function initRoutes(){
        $p=$_GET['p']??$GLOBALS['config']['app']['dp'];
        $c=$_GET['c']??$GLOBALS['config']['app']['dc'];
        $a=$_GET['a']??$GLOBALS['config']['app']['da'];
        $p=ucfirst(strtolower($p));
        $c=ucfirst(strtolower($c));		//首字母大寫(xiě)
        $a=strtolower($a);			//轉(zhuǎn)成小寫(xiě)
        define('PLATFROM_NAME', $p);    //平臺(tái)名常量
        define('CONTROLLER_NAME', $c);  //控制器名常量
        define('ACTION_NAME', $a);      //方法名常量
        define('__URL__', CONTROLLER_PATH.$p.DS);   //當(dāng)前請(qǐng)求控制器的目錄地址
        define('__VIEW__',VIEW_PATH.$p.DS);     //當(dāng)前視圖的目錄地址
    }
    //自動(dòng)加載類
    private static function initAutoLoad(){
        spl_autoload_register(function($class_name){
            $namespace= dirname($class_name);   //命名空間
            $class_name= basename($class_name); //類名
            if(in_array($namespace, array('Core','Lib')))   //命名空間在Core和Lib下
                $path= FRAMEWORK_PATH.$namespace.DS.$class_name.'.class.php';
            elseif($namespace=='Model')     //文件在Model下
                $path=MODEL_PATH.$class_name.'.class.php';
            elseif($namespace=='Traits')    //文件在Traits下
                $path=TRAITS_PATH.$class_name.'.class.php';
            else   //控制器
                $path=CONTROLLER_PATH.PLATFROM_NAME.DS.$class_name.'.class.php'; 
            if(file_exists($path) && is_file($path))
                require $path;
        });
    }
    //請(qǐng)求分發(fā)
    private static function initDispatch(){
        $controller_name='Controller\'.PLATFROM_NAME.'\'.CONTROLLER_NAME.'Controller';	//拼接控制器類名
        $action_name=ACTION_NAME.'Action';	//拼接方法名
        $obj=new $controller_name();
        $obj->$action_name();
    } 
}

配置文件

# Application/Config/config.php
<?php
return array(
    //數(shù)據(jù)庫(kù)配置
    'database'=>array(),
    //應(yīng)用程序配置
    'app'=>array(
        'dp' => 'Admin',        //默認(rèn)平臺(tái)
        'dc' => 'Products',     //默認(rèn)控制器
        'da' => 'list'          //默認(rèn)方法
    )
);
?>

基礎(chǔ)模型

# Framework/Core/Model.class.php
<?php
namespace Core;
class Model {
    protected $mypdo;
    public function __construct(){
        $this->initMyPDO();
    }
    // 連接數(shù)據(jù)庫(kù)
    private function initMyPDO(){
        $this->mypdo= MyPDO::getInstance($GLOBALS['config']['database']);
    }
}
?>

PDO數(shù)據(jù)庫(kù)

# Framework/Core/MyPDO.class.php
<?php
namespace Core;
class MyPDO{
    private $type;      //數(shù)據(jù)庫(kù)類別
    private $host;      //主機(jī)地址
    private $port;      //端口號(hào)
    private $dbname;    //數(shù)據(jù)庫(kù)名
    private $charset;   //字符集
    private $user;      //用戶名
    private $pwd;       //密碼
    private $pdo;       //保存PDO對(duì)象
    private static $instance;
    private function __construct($param) {
        $this->initParam($param);
        $this->initPDO();
        $this->initException();
    }
    private function __clone() {
    }
    public static function getInstance($param=array()){
        if(!self::$instance instanceof self)
            self::$instance=new self($param);
        return self::$instance;
    }
    //初始化參數(shù)
    private function initParam($param){
        $this->type=$param['type']??'mysql';
        $this->host=$param['host']??'127.0.0.1';
        $this->port=$param['port']??'3306';
        $this->dbname=$param['dbname']??'data';
        $this->charset=$param['charset']??'utf8';
        $this->user=$param['user']??'root';
        $this->pwd=$param['pwd']??'';
    }
    //初始化PDO
    private function initPDO(){
        try{
            $dsn="{$this->type}:host={$this->host};port={$this->port};dbname={$this->dbname};charset={$this->charset}";
            $this->pdo=new PDO($dsn, $this->user, $this->pwd);
        } catch (PDOException $ex) {
            $this->showException($ex);
            exit;
        }
    }
    
    //顯示異常
    private function showException($ex,$sql=''){
        if($sql!=''){
            echo 'SQL語(yǔ)句執(zhí)行失敗<br>';
            echo '錯(cuò)誤的SQL語(yǔ)句是:'.$sql,'<br>';
        }
        echo '錯(cuò)誤編號(hào):'.$ex->getCode(),'<br>';
        echo '錯(cuò)誤行號(hào):'.$ex->getLine(),'<br>';
        echo '錯(cuò)誤文件:'.$ex->getFile(),'<br>';
        echo '錯(cuò)誤信息:'.$ex->getMessage(),'<br>';
    }
    //設(shè)置異常模式
    private function initException(){
        $this->pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    }

    //執(zhí)行增、刪、改操作
    public function exec($sql){
        try{
            return $this->pdo->exec($sql);
        } catch (PDOException $ex) {
            $this->showException($ex, $sql);
            exit;
        }
    }
    //獲取自動(dòng)增長(zhǎng)的編號(hào)
    public function lastInsertId(){
        return $this->pdo->lastInsertId();
    }

    //判斷匹配的類型
    private function fetchType($type){
        switch ($type){
            case 'num':
                return PDO::FETCH_NUM;
            case 'both':
                return PDO::FETCH_BOTH;
            case 'obj':
                return PDO::FETCH_OBJ;
            default:
                return PDO::FETCH_ASSOC;
        }
    }
    //獲取所有數(shù)據(jù) ,返回二維數(shù)組
    public function fetchAll($sql,$type='assoc'){
        try{
            $stmt=$this->pdo->query($sql);  //獲取PDOStatement對(duì)象
            $type= $this->fetchType($type); //獲取匹配方法
            return $stmt->fetchAll($type);
        } catch (Exception $ex) {
            $this->showException($ex, $sql);
        }
    }
    //獲取一維數(shù)組
    public function fetchRow($sql,$type='assoc'){
        try{
            $stmt=$this->pdo->query($sql);  //獲取PDOStatement對(duì)象
            $type= $this->fetchType($type); //獲取匹配方法
            return $stmt->fetch($type);
        } catch (Exception $ex) {
            $this->showException($ex, $sql);
            exit;
        }
    }
    //返回一行一列
    public function fetchColumn($sql){
        try{
             $stmt=$this->pdo->query($sql);
            return $stmt->fetchColumn();
        } catch (Exception $ex) {
            $this->showException($ex, $sql);
            exit;
        }
    }
}
?>

控制器

# Application/Controller/Admin/ProductsController.class.php
<?php
namespace ControllerAdmin;
// 商品模塊
class ProductsController {
    use TraitsJump;
    // 獲取商品列表
    public function listAction(){
        // 實(shí)例化數(shù)據(jù)模型
        $model= new ModelProductsModel();
        $list= $model->getList();
        // 加載視圖
        require __VIEW__.'products_list.html';
    }
    public function delAction(){
        $id= (int)$_GET['proid'];
        $model= new ModelProductsModel();
        if($model->del($id)){
            $this->success('index.php?p=Admin&c=Products&a=list', '刪除成功');
        }else{
            $this->error('index.php?p=admin&c=Products&a=list', '刪除失敗');
        }
    }
}
?>

方法模型

# Application/Model/ProductsModel.class.php
<?php
namespace Model;
//products模型用來(lái)操作products表
class ProductsModel extends CoreModel{
    // 獲取products表的數(shù)據(jù)
    public function getList(){
        // 獲取商品數(shù)據(jù)
        return $this->mypdo->fetchAll('select * from products');
    }
    // 刪除products表的數(shù)據(jù)
    public function del($proid){
        // 刪除商品數(shù)據(jù)
        return $this->mypdo->exec("delete from products where proID={$proid}");
    }
}
?>

視圖

# Application/View/Admin/products_list.html
<!Doctype html>
<html>
<head>
<meta charset="utf-8">
<title>顯示商品</title>
</head>
<body>
	<table border='1' width='980' bordercolor='#000'>
		<tr>
			<th>編號(hào)</th> 
			<th>名稱</th> 
			<th>價(jià)格</th> 
			<th>刪除</th>
		</tr>
		<?php foreach($list as $rows):?>
		<tr>
			<td><?=$rows['proID']?></td>
			<td><?=$rows['proname']?></td>
			<td><?=$rows['proprice']?></td>
			<td><a href="index.php?p=Admin&c=Products&a=del&proid=<?=$rows['proID']?>" onclick="return confirm('確定要?jiǎng)h除嗎')">刪除</a></td>
		</tr>
		<?php endforeach;?>
	</table>
</body>
</html>

復(fù)用跳轉(zhuǎn)

# Traits/Jump.class.php
<?php
//跳轉(zhuǎn)的插件
namespace Traits;
trait Jump{
    //封裝成功的跳轉(zhuǎn)
    public function success($url,$info='',$time=1){
        $this->redirect($url, $info, $time, 'success');
    }
    //封裝失敗跳轉(zhuǎn)
    public function error($url,$info='',$time=3){
        $this->redirect($url, $info, $time, 'error');
    }
    /*
     * 作用:跳轉(zhuǎn)的方法
     * @param $url string 跳轉(zhuǎn)的地址
     * @param $info string 顯示信息
     * @param $time int 停留時(shí)間
     * @param $flag string 顯示模式  success|error
     */
    private function redirect($url,$info,$time,$flag){
        if($info=='')
            header ("location:{$url}");
        else{
          echo <<<str
            <!DOCTYPE html>
            <html lang="en">
            <head>
                <meta charset="UTF-8">
                <!--
                <meta http-equiv="refresh" content="3;http://www.php.com"/>
                -->
                <title>Document</title>
            <style>
            body{
                text-align: center;
                font-family: '微軟雅黑';
                font-size: 18px;
            }
            #success,#error{
                font-size: 36px;
                margin: 10px auto;
            }
            #success{
                color: #090;
            }
            #error{
                color: #F00;
            }
            </style>
            </head>
            <body>
                <img src="./Public/images/{$flag}.fw.png">
                <div id='{$flag}'>{$info}</div>
                <div><span id='t'>{$time}</span>秒以后跳轉(zhuǎn)</div>
            </body>
            </html>
            <script>
            window.onload=function(){
                var t={$time};
                setInterval(function(){
                    document.getElementById('t').innerHTML=--t;
                    if(t==0)
                        location.href='index.php';
                },1000)
            }
            </script>
            str;
        exit;
        }
    }
}

總結(jié)

以上是生活随笔為你收集整理的PHP核心之MVC设计模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。