Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:有二点澄清一下:
1. MVC是编程思想,并非设计模式,类似的还是MVVM
2. MVC并非只在TP,Laravel中应用, 只要涉及前后端合作开发, 都可以使用它
MVC作为一种常用的设计模式,得到了如TP5、Laravel等框架的广泛采用。
下面以电影表为例进行实践
连接数据库
<?php
/**
* 数据库的基本操作
*/
//7个方法实现两类功能:1.创建当前类的单一实例 2.创建数据库的基本操作
//use PDO;
class Db
{
//单例模式--$instance本类的实例
private static $instance = null;
//连接数据库
private $pdo = null;
//数据库的默认连接参数
private $dbConfig=[
'db'=>'mysql',
'host'=>'localhost',
'port'=>'3306',
'dbname'=>'anguoguo',
'user'=>'root',
'password'=>'root',
// 'charset'=>'utf8'//默认字符集有无必要设置
];
public $insertId = null;//新增主键id
public $num = 0;//新增更改记录
private function __construct($params)
{
//初始化连接参数--因用户可能有自定义的一些参数
$this->dbConfig = array_merge($this->dbConfig,$params);//数组合并
//连接数据库
$this->connect();
}
//禁止外部克隆
private function __clone()
{
// TODO: Implement __clone() method.
}
public static function getInstance($params=[]){
if(!self::$instance instanceof self){
self::$instance = new self($params);
}
return self::$instance;//获取类的单一实例
}
private function connect(){//连接数据库还是在本类中使用,故使用private
try {
//数据源
$dsn = "{$this->dbConfig['db']}:host={$this->dbConfig['host']};
port={$this->dbConfig['port']};dbname={$this->dbConfig['dbname']}";
//创建PDO对象
$this->pdo = new PDO($dsn,$this->dbConfig['user'],$this->dbConfig['password']);
// //设置客户端默认字符集 pdo中读和写分开,写是exec,查询是query
// $this->pdo->query("SET NAMES {$this->dbConfig['charset']}");
}catch (PDOException $error){
die('数据库连接失败' . $error->getMessage());
}
}
//数据表的写操作:增、删、改 && 返回受影响的记录
public function exec($sql){
$num = $this->pdo->exec($sql);
if($num>0){
if(!empty($this->pdo->lastInsertId())){//null !==
$this->insertId = $this->pdo->lastInsertId();
}
$this->num = $num;//返回受影响的记录
}else{
$error = $this->pdo->errorInfo();//获取最后操作的的错误信息数组
print '操作失败'.$error[0].':'.$error[1].':'.$error[2];
}
}
//获取单条查询结果
public function fetch($sql){
return $this->pdo->query($sql)->fetch(PDO::FETCH_ASSOC);
}
//获取多条查询结果
public function fetchAll($sql){
return $this->pdo->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
}
Model.php公共模型类—完成数据库连接及一些公共方法
<?php
class Model
{
protected $db = null;//只给子类调用,数据库连接对象
public $data = null;
public function __construct()
{
$this->init();//初始化的方法,完成数据库链接
}
private function init(){
$dbConfig = [
'dbname'=>'anguoguo',
'user'=>'root',
'password'=>'root',
];//Db.php中已经定义了---这里是用户的自定义参数,即params
//自定义链接配置覆盖默认参数
$this->db = Db::getInstance($dbConfig);
}
//获取单条数据
public function get($id){
$sql = "SELECT * FROM movies WHERE id={$id}";
return $this->data = $this->db->fetch($sql);
}
//获取全部数据
public function getAll(){
$sql = "SELECT * FROM movies";
return $this->data = $this->db->fetchAll($sql);
}
}
MoviesModel.php放用户自定义的方法
<?php
//用户自定义模型
class MoviesModel extends Model
{
//可以扩展功能
}
MoviesController.php用户自定义模型对应的控制器
<?php
/**
* 电影模块控制器类通常包括:查询,更新,添加,删除
* 模型根据数据表建立,控制器根据模块创建
* 所以一个控制器要完成一个模块的功能,这里完成的查询功能
*/
//一张表对应一个模型 控制器中的方法大多是模型操作的具体实现 大多数控制器类的方法都有对应视图文件
class MoviesController//用户自定义控制器,加Controller方便自动加载和明确操作
{
public function listAll(){
//实例化模型,获取数据
$mov = new MoviesModel();
$data = $mov->getAll();//来自父类Model中的方法
// echo '<pre>';//格式化方便查看
// print_r($data);
// 有了视图文件后取代上面的打印
require "H:/Programfile/phpstudy_pro/WWW/html/lecture/easymvc/mvc/view/movies_list.php";
//用相对路径会出错
}
//获取单条数据
public function info($id=1){
$id = isset($_GET['mov_id'])? $_GET['mov_id']:$id;
$mov = new MoviesModel();
$data = $mov->get($id);//来自父类Model中的方法
echo '<pre>';
print_r($data);
}
}
index.php项目的入口文件
<?php
//前端控制器--请求分发器,入口文件功能
//加载模型类
require 'model/Db.php';
require 'model/Model.php';
require 'model/MoviesModel.php';
//加载控制器 路由 控制器及控制器中方法
$controller = isset($_GET['c']) ? $_GET['c'] : 'Movies';//判断当前url中是否有c--controller
$controller .= 'Controller';//给控制器添加后缀名
//require 'controller/MoviesController.php';//加载控制器类,方便调用方法
require 'controller/' . $controller . '.php';//加载控制器类,方便调用方法
$action = isset($_GET['a']) ? $_GET['c'] : 'listAll';//获取方法
$mov = new $controller();//实例化自定义控制器类
$mov->$action();//根据电影id,默认为1
用fetch的数据渲染html页面
<!--视图一般用模板引擎来写-->
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MVC示例</title>
</head>
<body>
<h2 align="center">电影目录</h2>
<table border="1" cellpadding="5" cellspacing="0" align="center" width="70%">
<tr bgcolor="#6495ed">
<th>ID</th>
<th>片名</th>
<th>图片</th>
<th>详情</th>
<th>分类</th>
</tr>
<?php foreach ($data as $mov): ?>
<!-- MoviesController赋的变量为$data-->
<tr align="center">
<td><?php echo $mov['mov_id']; ?></td>
<td><?php echo $mov['name']; ?></td>
<td><?php echo $mov['image']; ?></td>
<td><?php echo $mov['detail']; ?></td>
<td><?php echo $mov['cate_id']; ?></td>
</tr>
<?php endforeach;?>
</table>
<p align="center">共计:<?php echo count($data); ?>条记录</p>
</body>
</html>
渲染后效果如下: