MVC设计模式

一、概念

  MVC:M (model模型) —— V (view视图) —— C (control控制)
  MVC是一种经典设计模式,其中M(model模型)、V(view视图)、C(control控制),访问者通过请求访问控制层C,C调度M模型获取所需要的信息数据,然后再去加载V视图将节后整合后响应给访问者。

  基于MVC主要是为了解耦合(高内聚,低耦合),优点:易维护、易扩展。MVC结构升级是通过添加内容即可升级。

  使用MVC设计模式搭建的项目结构叫框架
  MVC是一个框架模式,它强制性的使应用程序的输入、处理和输出分开。

二、搭建一个简单的MVC框架

  1. 创建目录:
    ORG              第三方扩展类
    model            M(模型)层目录(M)
    controller           C(控制)层目录(C)
    view             V(视图) 层目录(smarty的模板目录)
    public              公共资源目录
    libs              Smarty库(解压到这里即可)
    view_c             Smarty模板编译目录(可选)
    cache               Smarty静态缓存目录(可选)
    configs             配置文件目录

    index.php          入口文件

  2.在model目录下创建Model.php类

Model.php

  1 <?php
  2 //单表信息操作类
  3 class Model
  4 {
  5     protected $tabname; //表名
  6     protected $link=null; //数据库连接对象
  7     protected $pk = "id"; //主键名
  8     protected $fields=array(); //表字段
  9     protected $where = array(); //查询条件
 10     protected $order = null; //排序
 11     protected $limit = null; //分页
 12     
 13     //构造方法
 14     public function __construct($tabname)
 15     {
 16         $this->tabname = $tabname;
 17         //连接数据库
 18         $this->link = mysqli_connect(HOST,USER,PASS,DBNAME) or die("数据库连接失败!");
 19         //设置字符编码
 20         mysqli_set_charset($this->link,"utf8");
 21         //初始化表字段信息
 22         $this->loadFields();
 23     }
 24     
 25     //加载当前表字段信息
 26     private function loadFields()
 27     {
 28         $sql = "desc {$this->tabname}";
 29         $result = mysqli_query($this->link,$sql);
 30         //解析结果
 31         while($row = mysqli_fetch_assoc($result)){
 32             //封装字段
 33             $this->fields[] = $row['Field'];
 34             //判断是否是主键
 35             if($row['Key']=="PRI"){
 36                 $this->pk = $row['Field'];
 37             }
 38         }
 39         mysqli_free_result($result);
 40     }
 41     
 42     //数据查询
 43     public function findAll()
 44     {
 45         $sql = "select * from {$this->tabname}";
 46         $result = mysqli_query($this->link,$sql);
 47         $list = mysqli_fetch_all($result,MYSQLI_ASSOC);
 48         mysqli_free_result($result);
 49         return $list;
 50     }
 51     //数据详情
 52     public function find($id)
 53     {
 54         $sql = "select * from {$this->tabname} where {$this->pk}={$id}";
 55         $result = mysqli_query($this->link,$sql);
 56         $list = mysqli_fetch_assoc($result);
 57         mysqli_free_result($result);
 58         return $list;
 59     }
 60     
 61     //数据查询
 62     public function select()
 63     {
 64         $sql = "select * from {$this->tabname}";
 65         
 66         //判断封装搜索条件
 67         if(!empty($this->where)){
 68             $sql .= " where ".implode(" and ",$this->where); 
 69         }
 70         //判断封装排序
 71         if(!empty($this->order)){
 72             $sql .= " order by ".$this->order;
 73         }
 74         //判断封装分页
 75         if(!empty($this->limit)){
 76             $sql .= " limit ".$this->limit;
 77         }
 78         
 79         $result = mysqli_query($this->link,$sql);
 80         $list = mysqli_fetch_all($result,MYSQLI_ASSOC);
 81         mysqli_free_result($result);
 82         //释放搜索和分页等条件
 83         $this->where = array();
 84         $this->order = null;
 85         $this->limit = null;
 86         
 87         echo $sql."<br/>";
 88         
 89         return $list;
 90     }
 91     
 92     //获取数据条数
 93     public function total()
 94     {
 95         $sql = "select count(*) as m from {$this->tabname}";
 96         
 97         //判断封装搜索条件
 98         if(!empty($this->where)){
 99             $sql .= " where ".implode(" and ",$this->where); 
100         }
101         //执行查询并解析
102         $result = mysqli_query($this->link,$sql);
103         $row = mysqli_fetch_assoc($result);
104         return $row["m"];
105     }
106     
107     //添加方法
108     public function insert($data=array())
109     {   //判断参数是否为空
110         if(empty($data)){
111             $data = $_POST; //就尝试从POST中获取
112         }
113         //定义用于存储字段和值信息变量
114         $fieldlist = array();
115         $valuelist = array();
116         //遍历并过要添加的值
117         foreach($data as $k=>$v){
118             //判断是否是有效字段
119             if(in_array($k,$this->fields)){
120                 $fieldlist[] = $k;
121                 $valuelist[] = "'".$v."'";
122             }
123         }
124         //拼装sql语句
125         $sql = "insert into {$this->tabname}(".implode(",",$fieldlist).") values(".implode(",",$valuelist).")";
126         //echo $sql;
127         //发送执行
128         mysqli_query($this->link,$sql);
129         //返回结果(自增id主键)
130         return mysqli_insert_id($this->link);
131     }
132     
133     //信息修改方法
134     public function update($data=array())
135     {   //判断参数是否为空
136         if(empty($data)){
137             $data = $_POST; //就尝试从POST中获取
138         }
139         //定义用于存储字段和修改值信息变量
140         $fieldlist = array();
141         //遍历并过要编辑的值
142         foreach($data as $k=>$v){
143             //判断是否是有效字段,且不是主键
144             if(in_array($k,$this->fields) && $k!=$this->pk){
145                 $fieldlist[] = $k."='".$v."'";
146             }
147         }
148         //拼装sql语句
149         $sql = "update {$this->tabname} set ".implode(",",$fieldlist)." where {$this->pk}='{$data[$this->pk]}'";
150         //echo $sql;
151         //发送执行
152         mysqli_query($this->link,$sql);
153         //返回结果(影响行数)
154         return mysqli_affected_rows($this->link);
155     }
156     
157     
158     //数据删除
159     public function del($id)
160     {
161         $sql = "delete from {$this->tabname} where {$this->pk}={$id}";
162         mysqli_query($this->link,$sql);
163         return mysqli_affected_rows($this->link);
164     }
165     
166     //封装搜索
167     public function where($where)
168     {
169         $this->where[] = $where;
170         return $this;
171     }
172     
173     //封装排序
174     public function order($order)
175     {
176         $this->order = $order;
177         return $this;
178     }
179     
180     //封装分页
181     public function limit($m,$n=0)
182     {
183         if($n==0){
184             $this->limit = $m;
185         }else{
186             $this->limit = $m.",".$n;
187         }
188         return $this;
189     }
190      
191     
192     //析构方法,实现数据库关闭
193     public function __destruct()
194     {
195         if($this->link){
196             mysqli_close($this->link);
197         }
198     }
199     
200 }
View Code

  3.在ORG目录下创建Tpl.php类:用于初始化smarty

Tpl.php

 1 <?php
 2 //Smarty信息的初始化类
 3     class Tpl extends Smarty{
 4         public function __construct(){
 5             parent::__construct(); //构造父类
 6             //初始化Smarty对象中属性:
 7             $this->template_dir = "view";        //smarty模板目录
 8             $this->compile_dir = "view_c";        //smarty模板编译目录
 9 
10             $this->config_dir = "configs";    //smarty配置文件目录
11 
12             $this->cache_dir = "cache";        //smarty模板静态缓存目录
13             //$this->caching = true;            //是否开启静态缓存
14             //$this->cache_lifetime = 3600;        //静态缓存时间(秒)
15 
16             //指定定界符
17             $this->left_delimiter="{";    //左定界符
18             $this->right_delimiter="}";    //右定界符
19         }
20     }
View Code

  4.在controller目录下创建Controller类,继承Tpl类,文件名叫:Controller.php 所有控制器的基类

Controller.php

 1 <?php
 2 //Controller的控制基类
 3 class Controller extends Tpl{
 4     public function __construct(){
 5         parent::__construct();
 6     }
 7     
 8     /**
 9      *Controller初始化方法(在这个方法里根据参数a的值决定调用对应的方法)
10      *
11      */
12     public function init(){
13         //获取a参数的值
14         $a  = isset($_GET["a"])?$_GET["a"]:"index"; //默认值为index
15         //判断当前Controller是否存在此方法
16         if(method_exists($this,$a)){
17             //调用此方法
18             $this->$a();
19         }else{
20             die("没有找到{$a}对应的方法");
21         }    
22     }
23     
24 }
View Code

  继续添加IndexController.php控制器

1 <?php
2 class IndexController extends Controller
3 {
4     public function index()
5     {
6         echo "<h2>Hello World!</h2>";
7     }
8 }
View Code

  5.在最外层创建index.php入口文件:完成自动加载,查找相应的控制器

index.php

 1 <?php
 2 //网站的主入口程序
 3 
 4 //自动加载类
 5 function __autoload($name){
 6     //$name = strtolower($name);//转成小写
 7     if(file_exists("./controller/{$name}.php")){
 8         require("./controller/{$name}.php");
 9     }elseif(file_exists("./model/{$name}.php")){
10         require("./model/{$name}.php");
11     }elseif(file_exists("./ORG/{$name}.php")){
12         require("./ORG/{$name}.php");
13     }elseif(file_exists("./libs/".ucfirst($name).".class.php")){
14         require("./libs/".ucfirst($name).".class.php");
15     }elseif(file_exists("./libs/sysplugins/{$name}.php")){
16         require("./libs/sysplugins/{$name}.php");
17     }else{
18         die("错误:没有找到对应{$name}类!");
19     }
20 }
21 //数据连接配置文件
22 require("./configs/config.php");
23 
24 //获取参数m的值,并创建对应的Controller对象
25 $mod = isset($_GET['c'])?$_GET['c']:"index";
26 //拼装Controller类名
27 $classname = ucfirst($mod)."Controller";
28 //创建对应的Controller对象
29 $controller = new $classname();
30 
31 //执行Controller的初始化(Controller入口)
32 $controller->init();
View Code

  6.在configs目录下创建config.php配置文件:公共配置文件

1 <?php
2 //公共配置文件
3 
4 //数据库配置文件
5 define("HOST","localhost");
6 define("USER","root");
7 define("PASS","");
8 define("DBNAME","MVC");
View Code

访问入口文件显示:Hello World!

至此一个简单的MVC框架搭建成功!!!

做一个简单的学生信息增删改查,测试一下这个MVC框架

 controller目录下修改IndexController.php和添加StuController.php

1 <?php
2 class IndexController extends Controller
3 {
4     public function index()
5     {
6         echo "<h2>测试自己搭建的MVC框架--学生信息管理</h2>";
7         echo "<h3><a href='index.php?c=Stu&a=index'>1. 学生信息管理</a></h3>";
8     }
9 }
View Code
 1 <?php
 2 class StuController extends Controller
 3 {
 4     //显示学生信息
 5     public function index()
 6     {
 7         $mod = new Model("stu");
 8         $list = $mod->findAll();
 9         $this->assign("list",$list);
10         $this->display("index.html");
11     }
12     //删除学生信息
13     public function del()
14     {
15         $mod = new Model("stu");
16         $mod->del($_GET[id]+0);
17         header("Location:".$_SERVER["HTTP_REFERER"]);
18     }
19     //添加学生信息
20     public function add()
21     {
22         $this->display("add.html");
23     }
24     public function insert()
25     {
26         $mod =  new Model("stu");
27         $mod->insert();
28         header("Location:index.php?c=Stu&a=index");
29     }
30     //修改学生信息
31     public function edit()
32     {
33         $mod =  new Model("stu");
34         $stu=$mod->find($_GET['id']);
35         $this->assign("vo",$stu);
36         $this->display("edit.html");
37 
38     }
39     public function update()
40     {
41         $mod =  new Model("stu");
42         $mod->update();
43         header("Location:index.php?c=Stu&a=index");
44     }
45 }
View Code

view目录下添加以下四个模板

menu.html

1         <h2>学生信息管理</h2>
2         <a href="index.php?c=Stu&a=index">浏览信息</a> |
3         <a href="index.php?c=Stu&a=add">添加信息</a>
4         <hr/>
View Code

index.html

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="utf-8"/>
 5     <title>学生信息管理</title>
 6 </head>
 7 <body>
 8 <center>
 9     {include file="menu.html" }
10 
11     <h3>浏览学生信息</h3>
12     <table width="600" border="1">
13         <tr>
14             <th>学号</th>
15             <th>姓名</th>
16             <th>性别</th>
17             <th>年龄</th>
18             <th>班级</th>
19             <th>操作</th>
20         </tr>
21         {foreach $list as $vo}
22             <tr>
23                 <td>{$vo.id}</td>
24                 <td>{$vo.name}</td>
25                 <td>{$vo.sex}</td>
26                 <td>{$vo.age}</td>
27                 <td>{$vo.classid}</td>
28                 <td>
29                     <a href="index.php?c=Stu&a=del&id={$vo.id}">删除</a>
30                     <a href="index.php?c=Stu&a=edit&id={$vo.id}">编辑</a>
31                 </td>
32             </tr>
33         {/foreach}
34     </table>
35 </center>
36 </body>
37 </html>
View Code

add.html

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title>学生信息管理</title>
 6     </head>
 7     <body>
 8         <center>
 9         {include file="menu.html"}
10         
11         <h3>添加学生信息</h3>
12         <form action="index.php?c=Stu&a=insert" method="post">
13         <table width="280" border="0">
14             <tr>
15                 <td  align="right">姓名:</td>
16                 <td><input type="text" name="name"/></td>
17             </tr>
18             <tr>
19                 <td align="right">性别:</td>
20                 <td>
21                     <input type="radio" name="sex" value="m"/>22                     <input type="radio" name="sex" value="w"/>23                 </td>
24             </tr>
25             <tr>
26                 <td align="right">年龄:</td>
27                 <td><input type="text" name="age"/></td>
28             </tr>
29             <tr>
30                 <td align="right">班级:</td>
31                 <td><input type="text" name="classid"/></td>
32             </tr>
33             <tr>
34                 <td colspan="2" align="center">
35                     <input type="submit" value="添加"/>
36                     <input type="reset" value="重置"/>
37                 </td>
38             </tr>
39         </table>
40         </form>
41         </center>
42        
43     </body>
44 </html>
View Code

edit.html

 1 <!DOCTYPE html>
 2 <html>
 3     <head>
 4         <meta charset="utf-8"/>
 5         <title>学生信息管理</title>
 6     </head>
 7     <body>
 8         <center>
 9         {include file="menu.html"}
10         
11         <h3>编辑学生信息</h3>
12         <form action="index.php?c=Stu&a=update" method="post">
13         <input type="hidden" name="id" value="{$vo.id}"/>
14         <table width="280" border="0">
15             <tr>
16                 <td  align="right">姓名:</td>
17                 <td><input type="text" name="name" value="{$vo.name}"/></td>
18             </tr>
19             <tr>
20                 <td align="right">性别:</td>
21                 <td>
22                     <input type="radio" name="sex" value="m" {if $vo.sex=="m"}checked{/if} />23                     <input type="radio" name="sex" value="w" {if $vo.sex=="w"}checked{/if} />24                 </td>
25             </tr>
26             <tr>
27                 <td align="right">年龄:</td>
28                 <td><input type="text" name="age" value="{$vo.age}"/></td>
29             </tr>
30             <tr>
31                 <td align="right">班级:</td>
32                 <td><input type="text" name="classid" value="{$vo.classid}"/></td>
33             </tr>
34             <tr>
35                 <td colspan="2" align="center">
36                     <input type="submit" value="修改"/>
37                     <input type="reset" value="重置"/>
38                 </td>
39             </tr>
40         </table>
41         </form>
42         </center>
43        
44     </body>
45 </html>
View Code
原文地址:https://www.cnblogs.com/yexiang520/p/5755640.html