博客列表 >实例演示mvc框架与路由器

实例演示mvc框架与路由器

P粉479712293
P粉479712293原创
2022年12月22日 20:58:45692浏览

题目1:一个简单的mvc模型

1.mvc1/index.php文件

  1. <?php
  2. // *一个简单的mvc模型
  3. // * 模型: Model
  4. // *1.连接数据库
  5. $db = new PDO('mysql:dbname=phpedu1', 'root', 'root');
  6. // *2.$stmt作为预处理对象
  7. $stmt = $db->prepare('SELECT * FROM `staff` LIMIT ?');
  8. // *3.绑定参数
  9. $stmt->bindValue(1, 5, PDO::PARAM_INT);
  10. // *4.执行
  11. $stmt->execute();
  12. // *5.获取全部的关联数据
  13. $staffs = $stmt->fetchAll(PDO::FETCH_ASSOC);
  14. ?>
  15. <!-- 视图 View -->
  16. <!DOCTYPE html>
  17. <html lang="zh-CN">
  18. <head>
  19. <meta charset="UTF-8">
  20. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  21. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  22. <title>员工列表</title>
  23. </head>
  24. <body>
  25. <h3>员工列表</h3>
  26. <ul>
  27. <?php foreach ($staffs as $staff) : extract($staff) ?>
  28. <li><?=$id?> : <?=$name?>, <?=$sex ? '女' : '男'?> (
  29. <?=$email?> )
  30. </li>
  31. <?php endforeach ?>
  32. </ul>
  33. </body>
  34. </html>

2.浏览器效果图:

题目2:框架中的模型类 Model

1.mvc2/core/Model.php文件:

  1. <?php
  2. // *框架中的模型类 Model
  3. // *遵循psr-4条件
  4. namespace core;
  5. use PDO;
  6. // *为了不让用户直接实例化,把class Model作为抽象类
  7. abstract class Model
  8. {
  9. // *$db:连接对象,在这里把$db作为一个属性
  10. protected $db = null;
  11. // *1.其下的构造方法
  12. // *连接数据库
  13. //* 在实例化时,自动连接
  14. public function __construct($dsn, $username, $password)
  15. {
  16. $this->db = new PDO($dsn, $username, $password);
  17. }
  18. // *2. 其下的select()方法
  19. // *自定义模型: 与某一张数据表相关的类
  20. //* 获取全部数据
  21. public function select($num)
  22. {
  23. $sql = 'SELECT * FROM `staff` LIMIT ?;';
  24. $stmt = $this->db->prepare($sql);
  25. $stmt->bindParam(1, $num, PDO::PARAM_INT);
  26. $stmt->execute();
  27. return $stmt->fetchAll(PDO::FETCH_ASSOC);
  28. }
  29. // *3.其下的getOne()方法
  30. //* 获取某个数据( id )
  31. public function getOne($id)
  32. {
  33. $sql = 'SELECT * FROM `user` WHERE `id` = ? ;';
  34. $stmt = $this->db->prepare($sql);
  35. $stmt->bindParam(1, $id, PDO::PARAM_INT);
  36. $stmt->execute();
  37. return $stmt->fetch(PDO::FETCH_ASSOC);
  38. }
  39. }

2.浏览器效果图:

题目3:框架中的视图类View

1.mvc2/core/View.php文件:

  1. <?php
  2. //*框架中的视图类View
  3. namespace core;
  4. class View
  5. {
  6. //* 1. 模板变量容器,专门用来存放模板变量,把它作为一个属性
  7. protected array $data = [];
  8. // *2. 其下的assign()方法,即模板赋值
  9. public function assign(string $key, $value)
  10. {
  11. $this->data[$key] = $value;
  12. }
  13. // *3.其下的render()方法,即渲染视图
  14. // *渲染与传参可以同步完成
  15. // *$path:数据显示在页面中的路径,$data为渲染时传参
  16. public function render(string $path, array $data=[])
  17. {
  18. // *如果渲染时传参有参数
  19. if ($data) {
  20. // *参数以每个键为单位遍历
  21. foreach ($data as $key=>$value) {
  22. // *调用其assign()方法,即在参数中分配键与键值
  23. $this->assign($key, $value);
  24. }
  25. }
  26. //* 将模板变量数组展开为独立的变量,以方便传入到模板中使用
  27. extract($this->data);
  28. // *如果当前的页面路径存在则加载,反之程序不执行
  29. file_exists($path) ? include $path : die('模板不存在');
  30. }
  31. }

2.浏览器效果图:

题目4:框架中的控制器类

1.mvc2/core/Controller.php文件:

  1. <?php
  2. // *框架中的控制器类View
  3. namespace core;
  4. // *为了不让用户直接实例化,把class Controller作为抽象类
  5. abstract class Controller
  6. {
  7. //* 1. 模型对象
  8. protected Model $model;
  9. //* 2. 视图对象
  10. protected View $view;
  11. //* 3.其下的构造函数,即实例化,初始化上面的模型,视图对象
  12. public function __construct(Model $model, View $view)
  13. {
  14. $this->model = $model;
  15. $this->view = $view;
  16. }
  17. }

2.浏览器效果图:

题目5:注册类的自动加载器方法

1.mvc2/core/autoload.php文件:

  1. <?php
  2. // *注册类的自动加载器方法
  3. spl_autoload_register(function ($class) {
  4. // *表示用'/'替换'\'后面是类名加后缀.php
  5. require str_replace('\\', '/', $class) . '.php';
  6. // require str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
  7. ![](https://img.php.cn/upload/image/920/826/897/1671549125615508.jpg)
  8. });

2.浏览器效果图:

题目6:路由器中的QueryString与PATH_INFO这两种方法

1.router.php文件:

  1. <?php
  2. // 路由的本质: 是从url中解析出控制器,控制器方法,以及方法的参数
  3. // 1. controller: 控制器类名
  4. // 2. method: 控制器中的某个方法名
  5. // 3. params: 参数列表,以数组形式
  6. // 以上三种数据在url中的展示方式
  7. // 1. queryString: 查询字符串
  8. // 2. PATH_INFO: 路径信息, 位于查询字符串与当前脚本之间的路径信息
  9. // phpedu.io/one/two/demo1.php?查询字符串,以键值对方式,和&分开
  10. // phpedu.io/one/two/demo1.php?c=hello&m=method&p=aaa
  11. // c=hello&m=method&p=aaa
  12. // phpedu.io/one/two/demo1.php PATH_INFO ?c=hello&m=method&p=aaa
  13. // phpedu.io/one/two/demo1.php/user/index/100/200?c=hello&m=method&p=aaa
  14. // /user/index/100/200 : PATH_INFO
  15. // use JetBrains\PhpStorm\Internal\ReturnTypeContract;()
  16. function p($data)
  17. {
  18. echo is_array($data) ? sprintf('<pre>%s</pre>', print_r($data, true)) : $data.'<br>';
  19. }
  20. // p([1,2,3]);
  21. // p('hello');
  22. p($_SERVER['QUERY_STRING']);
  23. parse_str($_SERVER['QUERY_STRING'],$request);
  24. p($request);
  25. $controller=array_shift($request);
  26. $method=array_shift($request);
  27. $params=array_shift($request);
  28. // *再自定义一个控制器类
  29. class HelloController
  30. {
  31. public function world($name)
  32. {
  33. return 'Hello, ' . $name;
  34. }
  35. }
  36. // *生成控制器类名,并且首字母大写
  37. echo ucfirst($controller).'Controller'.'<br>';
  38. $controller= ucfirst($controller). 'Controller';
  39. echo call_user_func_array([new $controller(), $method], [$params]);
  40. echo '<hr>';
  41. p($_SERVER['PATH_INFO']);
  42. p(explode('/', trim($_SERVER['PATH_INFO'], '/')));
  43. $request = explode('/', trim($_SERVER['PATH_INFO'], '/'));
  44. // * QueryString: 查询字符串
  45. // p($_SERVER['QUERY_STRING']);
  46. // parse_str($_SERVER['QUERY_STRING'], $request);
  47. // p($request);
  48. // // *人为认为
  49. //*c: controller, m: method, name:params
  50. // $controller = array_shift($request);
  51. // $method = array_shift($request);
  52. // $params = array_shift($request);
  53. // *控制器类:测试专用
  54. // class HelloController
  55. // {
  56. // public function world($name)
  57. // {
  58. // return 'Hello, ' . $name;
  59. // }
  60. // }
  61. // *生成控制器类名
  62. // $controller= ucfirst($controller). 'Controller';
  63. // echo call_user_func_array([new $controller(), $method], [$params]);
  64. // echo '<hr>';
  65. // echo call_user_func_array([new $controller(), $method], [$params]);
  66. // echo '<hr>';
  67. // *PATH_INFO: 查询字符串与脚本之间路径信息
  68. // * http://phpLearn.io/13c/router.php/hello/world/admin?c=hello&m=world&name=peter
  69. // * PATH_INFO: /hello/world/admin
  70. // * 推荐使用PATH_INFO
  71. //* 通过 url 重写功能,可以将脚本的扩展名php隐藏
  72. //* http://phpLearn.io/13C/router.php/hello/world/admin
  73. // *http://phpLearn.io/13C/router/hello/world/admin

2.浏览器效果图:

题目7:入口文件

1.mvc3.index.php文件:

  1. <?php
  2. namespace mvc3;
  3. use model\UserModel;
  4. use core\View;
  5. use core\Router;
  6. // *入口文件: 测试
  7. //* 1. 类的自动加载器
  8. require __DIR__ . '/core/autoload.php';
  9. //* 路由解析
  10. // *路由器调用parse()得到控制器,方法等,然后保存到请求变量$request中
  11. $request = Router::parse();
  12. // *请求变量分别把保存的数据转移给控制器,方法,参数变量中
  13. $controller = array_shift($request);
  14. $method = array_shift($request);
  15. $params = array_shift($request);
  16. //* 生成控制器名称(首字母大写)
  17. $controller= 'controller\\'. ucfirst($controller). 'Controller';
  18. // echo $controller;
  19. // die;
  20. // *2. 实例化控制器
  21. $model = new UserModel('mysql:dbname=phpedu1', 'root', 'root');
  22. $view = new View();
  23. $user = new $controller($model, $view);
  24. // *3. 调用控制器中的方法
  25. call_user_func_array([$user, 'get'], $params);

2.浏览器效果图:

题目8:路由器类

1.mvc3/core/Router.php文件:

  1. <?php
  2. namespace core;
  3. // *路由器类
  4. class Router
  5. {
  6. public static function parse(): array
  7. {
  8. // *默认控制器,实际项目,应该来自配置文件,而不是在写死
  9. $controller = 'Index';
  10. $action = 'index';
  11. //* 参数列表
  12. $params = [];
  13. //* 判断是否存在pathinfo
  14. if (array_key_exists('PATH_INFO', $_SERVER) && $_SERVER['PATH_INFO'] !== '/') {
  15. // *为什么要判断 $_SERVER['PATH_INFO'] !== '/' ?
  16. // *因为: admin.php/ 时,$_SERVER['PATH_INFO'] = '/', 导致解析控制器失败
  17. $pathinfo = array_filter(explode('/', $_SERVER['PATH_INFO']));
  18. // *dump($pathinfo);
  19. // *考虑到index.php/ 情况, 这时pathinfo为空数组
  20. if (count($pathinfo) >= 2) {
  21. $controller = array_shift($pathinfo);
  22. $action = array_shift($pathinfo);
  23. $params = $pathinfo;
  24. } else {
  25. $controller = array_shift($pathinfo);
  26. }
  27. }
  28. //* 查看控制器,方法,参数
  29. // dump($controller, $action, $params);
  30. // *将这些数据返回出去
  31. return [$controller, $action, $params];
  32. }
  33. }

题目9:利用入口文件进行测试:

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