博客列表 >12月06日- mvc框架小案例

12月06日- mvc框架小案例

Eric
Eric原创
2019年12月09日 14:58:13952浏览
一、mvc案例相关技术点:
  • 1、容器:将类的实例化过程装入,提供绑定bind()与实现make()方法供外部调用
  • 2、门面:将注入依赖类的相关方法静态化,并进行统一管理
  • 3、外部对象依赖注入
  • 4、自动加载技术 - spl_autoload_register
  • 5、数组转变量技术 - list(...)
  • 6、单例模式 - 封装 pdo对象
  • 7、数据表与类的绑定 - setFetchMode();

相关文件:

autoload.php- 自动加载类

  1. class Loader{
  2. public static function load($className)
  3. {
  4. $path = $className.'.php';
  5. if (file_exists($path)){
  6. require $path;
  7. }else{
  8. echo $path . '不存在,请检查~~';
  9. }
  10. }
  11. }
  12. spl_autoload_register(['Loader','load']);

Db.php- Db类

  1. class Db
  2. {
  3. private static $pdo = null; // pdo实例
  4. private function __construct(...$params)
  5. {
  6. list($dsn, $username, $password) = $params;
  7. try {
  8. self::$pdo = new PDO($dsn, $username, $password);
  9. } catch (Exception $e) {
  10. die('数据库连接失败:'.$e->getMessage());
  11. }
  12. }
  13. //单例模式
  14. public static function getInstance(...$params){
  15. if (is_null(self::$pdo)){
  16. new self(...$params);
  17. }
  18. return self::$pdo;
  19. }
  20. //禁止外部访问克隆方法
  21. private function __clone()
  22. {
  23. // TODO: Implement __clone() method.
  24. }
  25. }

View.php- 视图类

  1. class View
  2. {
  3. public function fetch($data)
  4. {
  5. $table = '';
  6. $table .= '<table>';
  7. $table .= '<caption>学生信息表</caption>';
  8. $table .= '<tr><th>ID</th><th>名字</th><th>年龄</th><th>课程</th><th>入学时间</th></tr>';
  9. foreach ($data as $item){
  10. $table .= '<tr>';
  11. $table .= "<td>{$item->id}</td>";
  12. $table .= "<td>{$item->name}</td>";
  13. $table .= "<td>{$item->age}</td>";
  14. $table .= "<td>{$item->course}</td>";
  15. $table .= "<td>{$item->create_dt}</td>";
  16. $table .= '</tr>';
  17. }
  18. $table .= '</table>';
  19. return $table;
  20. }
  21. }
  22. echo '<style>
  23. table {border-collapse: collapse; border: 1px solid; width: 500px;height: 150px}
  24. caption {font-size: 1.2rem; margin-bottom: 10px;}
  25. tr:first-of-type { background-color:lightblue;}
  26. td,th {border: 1px solid;padding: 6px}
  27. td:first-of-type {text-align: center}
  28. </style>';

Model.php- 数据类

  1. class Model
  2. {
  3. private $pdo;
  4. public $id;
  5. private $name;
  6. private $age;
  7. private $course;
  8. private $create_dt;
  9. //属性重载
  10. public function __get($name)
  11. {
  12. return $this->$name;
  13. }
  14. public function __construct()
  15. {
  16. $this->pdo = Db::getInstance('mysql:host=demo.com;dbname=demo','root','root');
  17. $this->create_dt = date('Y-m-d',$this->create_dt);
  18. }
  19. /**
  20. * 返回所有学生数据
  21. * @return array
  22. */
  23. public function getData(){
  24. $sql = 'select * from `student`';
  25. $stmt = $this->pdo->prepare($sql);
  26. $stmt->setFetchMode(PDO::FETCH_CLASS, Model::class);
  27. $stmt->execute();
  28. $students = $stmt->fetchAll();
  29. return $students;
  30. }
  31. }

Container.php- 容器类

  1. class Container
  2. {
  3. //类实例的容器
  4. protected $instance = [];
  5. //绑定类实例到容器中
  6. public function bind($alias, Closure $closure){
  7. $this->instance[$alias] = $closure;
  8. }
  9. //将类实例从容器中取出来
  10. public function make($alias, $params = []){
  11. return call_user_func_array($this->instance[$alias],$params);
  12. }
  13. }

Facade.php- 门面类

  1. class Facade
  2. {
  3. //container实例
  4. protected static $container;
  5. //数据对象
  6. protected static $data = [];
  7. /**
  8. * 实例化方法
  9. * @param $container 将容器注入到本类中
  10. */
  11. public static function initialize(Container $container)
  12. {
  13. static::$container = $container;
  14. }
  15. //将 Model类的方法静态化,并由本类进行管理调用
  16. public static function getData($alias){
  17. static::$data = self::$container->make($alias)->getData();
  18. }
  19. //将 View类的方法静态化,并由本类进行管理调用
  20. public static function fetch($alias){
  21. return static::$container->make($alias)->fetch(static::$data);
  22. }
  23. }

Controller.php- 控制器类

  1. // 3、创建控制器
  2. class Controller
  3. {
  4. protected $container;
  5. public function __construct($container)
  6. {
  7. $this->container = $container;
  8. $this->container->bind('model',function (){return new Model();});
  9. $this->container->bind('view',function (){return new View();});
  10. // 调用 Facade里面的初始化方法
  11. Facade::initialize($container);
  12. }
  13. public function index()
  14. {
  15. // 获取数据
  16. Facade::getData('model');
  17. // 渲染模板
  18. return Facade::fetch('view');
  19. }
  20. }

index.php- 工作类

  1. //在工作类中引入一次即可
  2. <?php
  3. session_start();
  4. require 'autoload.php';
  5. if (!isset($_SESSION['user'])) {
  6. echo '<script>alert("请先登录");location.assign("login.php");</script>';
  7. }
  8. //客户端调用
  9. $container = new Container();
  10. $controller = new Controller($container);
  11. ?>
  12. <!DOCTYPE html>
  13. <html lang="en">
  14. <head>
  15. <meta charset="UTF-8">
  16. <title>后台管理界面</title>
  17. <link rel="stylesheet" href="css/main.css">
  18. </head>
  19. <body>
  20. <header>
  21. <h3>后台管理</h3>
  22. <nav>
  23. <a href="#">用户</a>
  24. <a href="dispatch.php?action=logout">退出</a>
  25. </nav>
  26. </header>
  27. <main>
  28. <aside>
  29. <li><a>首页</a></li>
  30. <li><a>学生信息</a></li>
  31. <li><a>用户管理</a></li>
  32. <li><a>系统设置</a></li>
  33. </aside>
  34. <article>
  35. <?php
  36. echo $controller->index();
  37. ?>
  38. </article>
  39. </main>
  40. <footer>
  41. <p>2019 - MVC模板案例</p>
  42. </footer>
  43. </body>
  44. </html>

代码效果:


二、路由解析

  1. $uri = $_SERVER['REQUEST_URI'];
  2. $request = explode('/',$uri);
  3. //将pathinfo内容解析到一个数组中保存
  4. $arr = array_slice($request , 3,3);
  5. list($module, $controller, $action) = $arr;
  6. $arr = compact('module','controller','action');
  7. print_r($arr);
  8. //从pathinfo数组中解析出:参数键值对
  9. $values = array_slice($request, 6);
  10. for ($i=0; $i<count($values); $i+=2) {
  11. // 将键值对中的第一个做为键,第二个做为值,该操作仅在第二个值存在的情况下执行
  12. if( isset($values[$i+1])) {
  13. $params[$values[$i]] = $values[$i+1];
  14. }
  15. }
  16. print_r($params);

课程总结:

1、mvc框架底层实现通过 控制器-Controller:控制器中有两个辅助类(Container负责把依赖类的实例注入到控制器中,Facade负责管理获取数据和渲染数据的方法)获取到模板数据-Model渲染到页面-View

2、router通过解析 uri可以获取到用户请求的模板、控制器和方法及参数,程序就会执行与之一一对应的代码并返回相应的页面。

THE END !

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议