博客列表 >路由原理与实现、视图基类、模型与查询构造器基类学习

路由原理与实现、视图基类、模型与查询构造器基类学习

阿杰
阿杰原创
2022年07月14日 14:58:47397浏览

一、路由原理与实现

  • 将模块、控制器和方法从pathinfo中解析出来

  • user.php

  1. <?php
  2. // 用模块当命名空间
  3. namespace admin;
  4. class User
  5. {
  6. public static function index($id,$name)
  7. {
  8. printf('id=%d,name=%s',$id,$name);
  9. }
  10. }
  • 实例
  1. <?php
  2. require __DIR__.'/../helper.php';
  3. // ! 主流路由解决方案:pathinfo
  4. $url = 'http://phpedu.com/0507/router/demo2.php?c=user&a=hello';
  5. p(pathinfo($url));
  6. // 这个pathinfo不是我们要的
  7. // 我们真正需要的是位于脚本名demo2.php与xxxx查询字符串之间的路径信息
  8. $url2 = 'http://phpedu.com/0507/router/demo2.php/one/two/three?c=user&a=hello';
  9. p(pathinfo($url2));
  10. // p($_SERVER['PATH_INFO']);
  11. // 以单一入口为例
  12. // index.php?m=模块,例如前台home,后台admin
  13. // 单入口
  14. // index.php/模块/控制器/方法
  15. // index.php/module/controller/action
  16. // 多入口
  17. // 前台:index.php 作为入口 不需要模块,controller/action
  18. // 后台:admin.php 作为入口 不需要模块,controller/action
  19. $url3 = 'http://phpedu.com/0507/router/demo2.php/admin/user/index';
  20. p($_SERVER['PATH_INFO']);
  21. p(explode('/',trim($_SERVER['PATH_INFO'],'/')));
  22. $request = explode('/',trim($_SERVER['PATH_INFO'],'/'));
  23. // 将模块、控制器和方法解析出来
  24. [$module,$controller,$action] = $request;
  25. printf('模块:%s<br>控制器:%s<br>方法:%s<br>',$module,$controller,$action);
  26. // 从pathinfo中解析出参数
  27. $url4 = 'http://phpedu.com/0507/router/demo2.php/admin/user/index/id/1/name/admin';
  28. require 'User.php';
  29. // admin\User::index(1,'张三');
  30. // 类名
  31. $className = $module.'\\'.ucfirst($controller);
  32. p($className);
  33. $params = array_splice($request,3);
  34. printf('<pre>%s</pre>',print_r($params,true));
  35. echo call_user_func_array([$className,$action],$params);
  36. // p(array_chunk([1, 2, 3, 4, 5, 6, 7], 2));
  37. $arr = array_chunk($params, 2);
  38. p($arr);
  39. $result = [];
  40. foreach ($arr as $item) {
  41. [$key, $value] = $item;
  42. $result[$key] = $value;
  43. }
  44. p($result);
  45. $result = array_filter($result);
  46. p($result);
  47. echo call_user_func_array([$className,$action],$result);
  • 路由访问

二、视图基类

  • 数据展示页面
  1. <body>
  2. <h3>User控制器的hello()方法</h3>
  3. <h3>Hello,<?=$username?></h3>
  4. <h3>Hello,<?=$items?></h3>
  5. <h3>Hello,<?=$lang?></h3>
  6. <ul>
  7. <?php foreach($items as ['name'=>$name,'price'=>$price]) : ?>
  8. <li><?=$name?> : <?=$price?></li>
  9. <?php endforeach ?>
  10. </ul>
  11. <ul>
  12. <?php foreach($lang as $value) : ?>
  13. <li><?=$value?></li>
  14. <?php endforeach ?>
  15. </ul>
  16. </body>
  • 视图基类
  1. <?php
  2. // 视图基类
  3. namespace phpcn;
  4. class View
  5. {
  6. // 约定:控制器方法的模板,默认一控制器为目录名,以方法为文件名
  7. protected $controller;
  8. protected $action;
  9. protected $path;
  10. // 模板变量容器
  11. protected $data = [];
  12. // 初始化时创建模板的路径
  13. public function __construct($controller,$action,$path = '/view/')
  14. {
  15. $this->controller = $controller;
  16. $this->action = $action;
  17. $this->path = $path;
  18. }
  19. // 模板赋值
  20. public function assign($name,$value){
  21. // $name 是外部变量 在模板文件 中的变量名
  22. // $value 就是 模板变量的值
  23. $this->data[$name] = $value;
  24. }
  25. // 模板渲染
  26. // 将模板赋值与模板渲染二合一
  27. public function render($path='',$name=null,$value=null)
  28. {
  29. if($name && $value) $this->assign($name,$value);
  30. // 展开模板变量数组
  31. extract($this->data);
  32. if(empty($path)){
  33. // 按约定规则来生成模板文件的路径并加载它
  34. $file = __DIR__ . $this->path . $this->controller .'/' . $this->action . '.php';
  35. }else{
  36. $file = $path;
  37. }
  38. file_exists($file) ? include $file : die('视图不存在');
  39. }
  40. }
  41. // 测试
  42. $controller = 'User';
  43. $action = 'hello';
  44. $view = new View($controller,$action);
  45. // 模板赋值:变量
  46. $view->assign('username','朱老师');
  47. $items = [
  48. ['name'=>'手机','price'=>15000],
  49. ['name'=>'电脑','price'=>25000],
  50. ['name'=>'相机','price'=>35000],
  51. ];
  52. $view->assign('items',$items);
  53. // 渲染模板
  54. // $view->render();
  55. // 渲染,赋值二合一
  56. $view->render($path = '', 'lang', ['php', 'java', 'python']);

三、模型与查询构造器基类

  • Db模型
  1. <?php
  2. namespace phpcn;
  3. use PDO;
  4. class Db
  5. {
  6. protected $db;
  7. protected $table;
  8. protected $field;
  9. protected $limit;
  10. protected $opt = [];
  11. public function __construct($dsn,$username,$password)
  12. {
  13. $this->db = new PDO($dsn,$username,$password);
  14. }
  15. public function table($table)
  16. {
  17. $this->table = $table;
  18. // 返回当前对象,方便后面链式调用
  19. return $this;
  20. }
  21. public function field($field)
  22. {
  23. $this->field = $field;
  24. return $this;
  25. }
  26. public function limit($limit=10)
  27. {
  28. $this->limit = $limit;
  29. $this->opt['limit'] = " LIMIT $limit";
  30. return $this;
  31. }
  32. // 分页
  33. public function page($page=1){
  34. // 偏移量:offset = (page-1)*limit
  35. $this->opt['offset'] = ' OFFSET '.($page-1)*$this->limit;
  36. return $this;
  37. }
  38. // 查询条件
  39. public function where($where = '')
  40. {
  41. $this->opt['where'] = " WHERE $where";
  42. return $this;
  43. }
  44. }

  • 查询构造器:查
  1. // 查询
  2. public function select()
  3. {
  4. // 拼装sql
  5. $sql = 'SELECT '.$this->field.' FROM '.$this->table;
  6. $sql .= $this->opt['where'] ?? null;
  7. $sql .= $this->opt['limit'] ?? null;
  8. $sql .= $this->opt['offset'] ?? null;
  9. echo $sql.'<hr>';
  10. $stmt = $this->db->prepare($sql);
  11. $stmt->execute();
  12. // 清空查询条件
  13. $this->opt['where'] = null;
  14. return $stmt->fetchAll();
  15. }
  16. $db = new Db('mysql:dbname=mydb','myshop','yzj123');
  17. // $result = $db->table('staff')->field('id,name,email')->select();
  18. $result = $db->table('staff')->field('id,name,email')
  19. ->where('id > 1')
  20. ->limit(2)
  21. ->page(3)
  22. ->select();
  23. require 'helper.php';
  24. p($result);

  • 查询构造器:插入
  1. // 插入
  2. public function insert($data)
  3. {
  4. // [a=>1,b=2] 'a=1, b=2'
  5. $str = '';
  6. foreach($data as $key=>$value){
  7. $str .= $key.' = "' . $value . '", ';
  8. }
  9. // $str.=',';
  10. // rtrim() 函数移除字符串右侧的空白字符或其他预定义字符 rtrim(string,charlist)
  11. $sql = 'INSERT '.$this->table.' SET '. rtrim($str,', ');
  12. echo $sql.'<hr>';
  13. $stmt = $this->db->prepare($sql);
  14. $stmt->execute();
  15. $this->opt['where'] = null;
  16. return $stmt->rowCount();
  17. }
  18. $n = $db->table('staff')->insert(['name'=> 'zhu', 'email' => 'zhu@php.cn', 'sex' => 1, 'password' => md5(123456)]);
  19. echo $n > 0 ? '新增成功<hr>' : '新增失败或没有数据被添加<hr>';

  • 查询构造器:更新
  1. // 更新
  2. public function update($data)
  3. {
  4. // [a=>1,b=>2] 'a=1,b=2'
  5. $str = '';
  6. foreach($data as $key=>$value){
  7. $str .= $key.' ="'.$value.'", ';
  8. }
  9. $sql = 'UPDATE '.$this->table.' SET '.rtrim($str,', ');
  10. $sql .= $this->opt['where'] ?? die('禁止无条件更新');
  11. echo $sql.'<hr>';
  12. $stmt = $this->db->prepare($sql);
  13. $stmt->execute();
  14. $this->opt['where'] = null;
  15. return $stmt->rowCount();
  16. }
  17. $n = $db->table('staff')->where('id = 10')->update(['name' => 'Mrs_K']);
  18. echo $n > 0 ? '更新成功<hr>' : '更新失败或没有数据被更新<hr>';

  • 查询构造器:删除
  1. // 删除
  2. public function delete()
  3. {
  4. $sql = 'DELETE FROM '.$this->table;
  5. $sql.= $this->opt['where'] ?? die('禁止无条件删除');
  6. echo $sql.'<hr>';
  7. $stmt = $this->db->prepare($sql);
  8. $stmt->execute();
  9. $this->opt['where'] = null;
  10. return $stmt->rowCount();
  11. }
  12. $n = $db->table('staff')->where('id = 10')->delete();
  13. echo $n > 0 ? '删除成功<hr>' : '删除失败或没有数据被删除<hr>';

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