批改状态:合格
老师批语:
MVC的全名是Model View Controller,是一种使用“模型-视图-控制器”设计创建Web应用程序的模式,同时提供了对HTML、CSS和JavaScript的完全控制,它是一种软件设计典范


<?php// 模型类namespace core;use PDO;abstract class Model{protected $db = null;//1.连接数据库 在实例化时自动连接public function __construct($dsn, $username, $password){$this->db = new PDO($dsn, $username, $password);}// 2.内置一些底层操作// 2.1 获取全部数据 $table 查询的表名public function getAll($table){$sql = "SELECT * FROM `$table` ;";$stmt = $this->db->prepare($sql);// $stmt->execute();if ($stmt->execute()) {return $stmt->fetchAll(PDO::FETCH_ASSOC);} else {print_r($stmt->errorInfo());}}// 2.2 指定获取多条数据 此案例只调用了此方法public function getData($table, $num){$sql = "SELECT * FROM `$table` LIMIT ?;";$stmt = $this->db->prepare($sql);$stmt->bindParam(1, $num, PDO::PARAM_INT);$stmt->execute();return $stmt->fetchAll(PDO::FETCH_ASSOC);}// 2.3 根据id查询一条数据public function getOne($table, $id){$sql = "SELECT * FROM `$table` WHERE `id`= ? ;";$stmt = $this->db->prepare($sql);$stmt->bindParam(1, $id, PDO::PARAM_INT);$stmt->execute();return $stmt->fetchAll(PDO::FETCH_ASSOC);}}
<?php// 视图类namespace core;class View{// 1. 模板变量容器protected array $data = [];// 2. 模板赋值public function assign(string $key, $value){$this->data[$key] = $value;}// 3. 渲染视图同时传参 $path 视图路径 $data存放参数的容器public function render(string $path, array $data = []){if ($data) {foreach ($data as $key => $value) {$this->assign($key, $value);}}// 解构数组容器 以数组的键作为变量名 方便在模板中使用extract($this->data);// 渲染/加载模板文件file_exists($path) ? include $path : die('模板不存在');}}
<?php// 控制器类namespace core;abstract class Controller{// 1.模型对象protected Model $model;// 2.视图对象protected View $view;// 3.在实例化时初始化模型对象与视图对象public function __construct(Model $model, View $view){$this->model = $model;$this->view = $view;}}
<?phpnamespace core;// 路由类class Router{public static function parse(): array{// 默认控制器,实际项目,应该来自配置文件,而不是在写死$controller = 'Index';$action = 'index';// 参数列表$params = [];// 判断是否存在pathinfoif (array_key_exists('PATH_INFO', $_SERVER) && $_SERVER['PATH_INFO'] !== '/') {// 为什么要判断 $_SERVER['PATH_INFO'] !== '/' ?// 因为: admin.php/ 时,$_SERVER['PATH_INFO'] = '/', 导致解析控制器失败$pathinfo = array_filter(explode('/', $_SERVER['PATH_INFO']));// dump($pathinfo);// 考虑到index.php/ 情况, 这时pathinfo为空数组if (count($pathinfo) >= 2) {$controller = array_shift($pathinfo);$action = array_shift($pathinfo);$params = $pathinfo;} else {$controller = array_shift($pathinfo);}}// 查看控制器,方法,参数// dump($controller, $action, $params);// 将这些数据返回出去return [$controller, $action, $params];}}
<?php// 自定义User模型namespace model;use core\Model;class UserModel extends Model{public function __construct($dsn, $username, $password){parent::__construct($dsn, $username, $password);}// 根据条件获取数据public function getLimitData($table,$num=10){return $this->getData($table,$num);}}
<?phpnamespace controller;use core\Controller;use core\Model;use core\View;class UserController extends Controller{public function __construct(Model $model, View $view){parent::__construct($model, $view);}// 获取user表中所有数据public function getLimitData($table,$num){// 1. 选择模型: 获取数据$users = $this->model->getLimitData($table,$num);// 2. 加载视图// 路径约定: view/控制器/方法名.php$this->view->render('view/user/getLimitData.php', ['users' => $users]);}}
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>分页展示数据</title><style>table {margin: auto;width: 600px;border-collapse: collapse;text-align: center;}table th,table td {border: 1px solid;padding: 5px;}table thead {background-color: lightcyan;}table caption {font-size: larger;margin-bottom: 8px;}body>p {display: flex;}p>a {text-decoration: none;color: #555;border: 1px solid;padding: 5px 10px;margin: 10px 2px;}.active {background-color: seagreen;color: white;border: 1px solid seagreen;}</style></head><body><table><caption><h3>用户信息表</h3></caption><thead><tr><th>ID</th><th>姓名</th><th>性别</th><th>邮箱</th><th>注册时间</th></tr></thead><tbody><?php foreach ($users as $user) :extract($user) ?><tr><td><?=$id?></td><td><?=$name?></td><td><?=$sex?'女':'男' ?></td><td><?=$email?></td><td><?=date('Y-m-d H:i:s',$register_data)?></td></tr><?php endforeach ?></tbody></table></body></html>
<?phpnamespace myMVC;use controller\UserController;use model\UserModel;use core\View;// 入口文件: 测试// 1.类的自动 composer的自动加载器require 'vendor/autoload.php';// 2. 实例化控制器$model = new UserModel('mysql:dbname=phpedu', 'root', 'root');$view = new View();$users = new UserController($model, $view);// 3. 调用控制器中的方法$users->getLimitData('user',15);
{"autoload": {"psr-4": {"core\\": "core","model\\": "model","controller\\": "controller"}},"require": {}}
配置完成后需执行
composer dumpautoload使之生效

路由的本质: 是从url中解析出控制器,控制器方法,以及方法的参数
以路由的方式获取数据http://phpedu.io/0824/myMVC/indexRouter.php/UserController/getLimitData/user&10
<?phpnamespace myMVC;use controller\UserController;use model\UserModel;use core\View;use core\Router;// 入口文件: 测试// 1.类的自动 composer的自动加载器require 'vendor/autoload.php';$request = Router::parse();// 路由解析$controller = array_shift($request);$action = array_shift($request);// 将参数分割转为数组$params = explode('&', array_shift($request)[0]);// print_r($params);//生成新的控制器名称$controller = 'controller\\' . ucfirst($controller) . 'Controller';// 2. 实例化控制器$model = new UserModel('mysql:dbname=phpedu', 'root', 'root');$view = new View();$users = new UserController($model, $view);// 3. 调用控制器中的方法call_user_func_array([$users, 'getLimitData'], $params);

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号