一、概念
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 }
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 }
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 }
继续添加IndexController.php控制器
1 <?php 2 class IndexController extends Controller 3 { 4 public function index() 5 { 6 echo "<h2>Hello World!</h2>"; 7 } 8 }
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();
6.在configs目录下创建config.php配置文件:公共配置文件
1 <?php 2 //公共配置文件 3 4 //数据库配置文件 5 define("HOST","localhost"); 6 define("USER","root"); 7 define("PASS",""); 8 define("DBNAME","MVC");
访问入口文件显示: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 }
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目录下添加以下四个模板
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/>
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>
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>
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>