Blogger Information
Blog 49
fans 0
comment 3
visits 23005
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
实例演示mvc框架与路由器
P粉479712293
Original
693 people have browsed it

题目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:利用入口文件进行测试:

Correcting teacher:PHPzPHPz

Correction status:qualified

Teacher's comments:
Statement of this Website
The copyright of this blog article belongs to the blogger. Please specify the address when reprinting! If there is any infringement or violation of the law, please contact admin@php.cn Report processing!
All comments Speak rationally on civilized internet, please comply with News Comment Service Agreement
0 comments
Author's latest blog post