PHP之MVC底层实现

本文阅读 2 分钟
首页 后端,MVC开发框架 正文

MVC框架

Model:模型类,数据库操作
View:视图类,展示到客户端
Controller:控制器,协调模型与视图

MVC目录架构:
36353-kh3zrcb12dr.png

  • 具体代码如下:
  • Model.php
namespace core;
use PDO;
abstract class Model
{
    protected $db;
    public function __construct($dsn,$username,$password)
    {
        $this->db = new PDO($dsn,$username,$password);
    }
    public function getAll($num)
    {
        $sql = "SELECT * FROM `bittel` LIMIT ?;";
        $stmt = $this->db->prepare($sql);
        $stmt->bindParam(1,$num,PDO::PARAM_INT);
        if($stmt->execute()){
            return $stmt->fetchAll(PDO::FETCH_ASSOC);
        }else{
            print_r($stmt->errorInfo());
            print_r($stmt->debugDumpParams());
        }

    }
}
  • View.php
namespace core;

class View
{
    //1.创建模板变量
    protected array $data = [];

    //2.模板赋值
    public function assign(string $key, $value)
    {
        $this->data[$key] = $value;
    }

    //3.模板渲染
    public function render($path, $data = [])
    {
        //判断是否有数据传入
        if ($data) {
            foreach ($data as $key => $value) {
                $this->assign($key, $value);
            }
        }
        //数组解构
        extract($this->data);

        file_exists($path) ? include $path : die('模板文件不存在');
    }
}
  • Controller.php
namespace core;

abstract class Controller
{
    //模型对象
    protected Model $model;
    //视图对象
    protected View $view;
    public function __construct($model,$view)
    {
        //初始化两个对象
        $this->view = $view;
       $this->model = $model;
   }
}
  • Router
namespace core;

//路由类

class Router
{
    public static function parse(){
        // 默认控制器,实际项目,应该来自配置文件,而不是在写死
        $controller = 'User';
        $action = 'user';
        // 参数列表
        $params = [];

        // 判断是否存在pathinfo
        if (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];
    }
}
  • 自定义模型 UserModel.php
use core\Model;

class UserModel extends Model
{
    public function __construct($dsn, $username, $password)
    {
        parent::__construct($dsn, $username, $password);
    }
}
  • 自定义控制器 UserController.php
use core\Model;

class UserModel extends Model
{
    public function __construct($dsn, $username, $password)
    {
        parent::__construct($dsn, $username, $password);
    }
}
  • view文件 user.php
<!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>
    </tr>
    </thead>
    <tbody>
    <?php foreach ($users as $user) :extract($user) ?>
        <tr>
            <td><?=$id?>
            </td>
            <td><?=$name?>
            </td>
            <td><?=$sex?'女':'男' ?>
            </td>
            <td><?=$email?>
            </td>
        </tr>
    <?php endforeach ?>
    </tbody>
</table>
</body>
</html>
  • 入口文件 1.index.php
namespace Mvc;
use controller\UserController;
use model\UserModel;
use core\View;
// 入口文件: 测试
// 1.类的自动 composer的自动加载器
require 'vendor/autoload.php';
// 2. 实例化控制器
$model = new UserModel('mysql:dbname=bittel', 'root', 'root');
//print_r($model);
//echo $model;
$view = new View();
$users = new UserController($model, $view);
// 3. 调用控制器中的方法
$users->getDate(10);
  • 入口文件 2. index1.php
namespace Mvc;


use core\Router;
use core\View;
use Model\UserModel;

require 'vendor/autoload.php';
require 'model/UserModel.php';

$request = Router::parse();


$controller = array_shift($request);
$method = array_shift($request);
$params = array_shift($request);

// 生成控制器名称
$controller=  'controller\\'. ucfirst($controller). 'Controller';
//echo $controller;
//die();
$model = new UserModel('mysql:dbname=bittel', 'root', 'root');
//print_r($model);
//echo $model;
$view = new View();
$users = new $controller($model, $view);

call_user_func_array([$users, 'getDate'], $params);
  • 效果如下:

03197-07tprr62upln.png

原创文章,作者:huixiang,如若转载,请注明出处:https://www.hui-xiang.cn/archives/210.html
-- 展开阅读全文 --
PHP会话控制/简单的登录注册功能
« 上一篇 08-23
thinkphp安装配置/数据库的增删改查
下一篇 » 08-30

相关推荐