博客列表 >路由原理与实现

路由原理与实现

晨
原创
2022年05月08日 15:05:48402浏览
  • 路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源
  • 实现原理:检测url的变化,截获url地址,从url中解析出控制器和方法、参数然后来匹配路由规则

方案1:GET请求,从查询字符串解析出控制器、方法、参数

-php代码演示

  1. <?php
  2. //导入助手函数
  3. require __DIR__ . '/../helper.php';
  4. $url = 'http://php.edu/0507/router/demo1.php?c=user&a=hello';
  5. //* 查询字符串:url问号后面的键值对:c=user&a-hello
  6. //1. parse_url() 本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分。
  7. p(parse_url($url)['query']);
  8. //? 2. $_SERVER['REQUEST_URI'],$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。'REQUEST_URI',URI 用来指定要访问的页面。
  9. p($_SERVER['REQUEST_URI']);
  10. p(parse_url($_SERVER['REQUEST_URI'])['query']);
  11. //3. $_SERVER['QUERY_STRING'] = parse_url($_SERVER['REQUEST_URI'])['query']
  12. p($_SERVER['QUERY_STRING']);
  13. //为处理方便,将字符串转为数组
  14. // parse_str parse_str(string $string, array &$result): void
  15. //如果 string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 )。
  16. // c = user & a = hello ===> ['c'=>'user', 'a'=>'hello']
  17. parse_str($_SERVER['QUERY_STRING'], $params);
  18. p($params);
  19. // 过虑一下空值
  20. $params = array_filter($params);
  21. echo '<hr color=red >';
  22. // 路由测试
  23. class UserController
  24. {
  25. public static function hello($id = 1, $name = 'zhu')
  26. {
  27. return "<h3>Hello id=$id, name=$name</h3>";
  28. }
  29. }
  30. // 约定: get参数中
  31. // c 表示控制器
  32. // a 表示控制器中的方法
  33. $controller = ucfirst(array_shift($params)) . 'Controller';
  34. $action = array_shift($params);
  35. // http://php.edu/0507/router/demo1.php?c=user&a=hello&id=12&name=peter
  36. echo call_user_func_array([$controller, $action], $params);
  37. ?>

助手函数文件helper.php代码

  1. <?php
  2. function p($name)
  3. {
  4. $type = gettype($name);
  5. switch (strtolower($type)) {
  6. case 'string':
  7. case 'integer':
  8. case 'double':
  9. echo $name .'<br>';
  10. break;
  11. case 'null':
  12. case 'boolean':
  13. echo var_export($name) . '<br>';
  14. break;
  15. case 'object':
  16. case 'array':
  17. printf('<pre>%s</pre>',print_r($name,true));
  18. break;
  19. default:
  20. echo '未定义类型';
  21. }
  22. }
  23. ?>

主流路由解决方案:pathinfo

  • pathinfo() 返回一个关联数组包含有 path 的信息
  • $_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。

    • $_SERVER[‘PATH_INFO’] 包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息,如果存在的话。例如,如果当前脚本是通过 URL http://www.example.com/php/path_info.php/some/stuff?foo=bar 被访问,那么 $_SERVER[‘PATH_INFO’] 将包含 /some/stuff

    测试代码

  1. <?php
  2. require __DIR__ . '/../helper.php';
  3. //! 主流路由解决方案:pathinfo pathinfo() 返回一个关联数组包含有 path 的信息
  4. $url = 'http://php.edu/0507/router/demo2.php?c=user&a=hello';
  5. p(pathinfo($url));
  6. // $_SERVER['PATH_INFO']
  7. // p($_SERVER['PATH_INFO']);
  8. // 以单一入口为例
  9. // index.php?m=模块,例如前台home,后台admin
  10. // 单入口
  11. // index.php/模块/控制器/方法
  12. // index.php/module/controller/action
  13. // 多入口
  14. // 前台: index.php 做为入口 不需要模块, controller/action
  15. // 后台: admin.php 做为入口, 不需要模块, controller/action
  16. // 按顺序传递参数
  17. $url = 'http://php.edu/0507/router/demo2.php/admin/user/index/5/admin';
  18. p($_SERVER['PATH_INFO']);
  19. p(explode('/', trim($_SERVER['PATH_INFO'], '/')));
  20. $request1= explode('/',trim($_SERVER['PATH_INFO'],'/'));
  21. // 将模块,控制器和方法解析出来
  22. [$module, $controller, $action] = $request1;
  23. require 'User.php';
  24. // 调用: admin\User::index()
  25. $className = $module . '\\' . ucfirst($controller);
  26. $params1 = array_splice($request1, 3);
  27. echo call_user_func_array([$className, $action], $params1);
  28. // 键值对传参
  29. // name/admin -> name = admin
  30. //测试时输入下面URL
  31. $url = 'http://php.edu/0507/router/demo2.php/admin/user/index/id/1/name/admin';
  32. $request2= explode('/',trim($_SERVER['PATH_INFO'],'/'));
  33. [$module, $controller, $action] = $request2;
  34. $params2 = array_splice($request2, 3);
  35. $arr = array_chunk($params2, 2);
  36. $result =[];
  37. foreach ($arr as $item) {
  38. [$key, $value] = $item;
  39. $result[$key] = $value;
  40. }
  41. $result = array_filter($result);
  42. echo call_user_func_array([$className, $action], $result);
  43. ?>

User类文件代码 User.php

  1. <?php
  2. namespace admin;
  3. use UserController;
  4. class User
  5. {
  6. public static function index($id, $name)
  7. {
  8. printf('id = %d, name = %s', $id, $name);
  9. }
  10. }
  11. ?>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议