路由

启用路由

服务器配置文件中加入中间件:

  1. return [
  2. 'beans' => [
  3. 'HttpDispatcher' => [
  4. 'middlewares' => [
  5. \Imi\Server\Http\Middleware\RouteMiddleware::class,
  6. ],
  7. ],
  8. ],
  9. ];

通过配置注入形式,实现非常灵活的配置,你甚至可以自己另外实现路由中间件,而不用被框架自带的中间件所影响,用哪些中间件都在你的掌控之中!

路由配置

  1. return [
  2. 'beans' => [
  3. 'HttpRoute' => [
  4. // url匹配缓存数量,默认1024
  5. 'urlCacheNumber' => 1024,
  6. // 全局忽略 URL 路由大小写
  7. 'ignoreCase' => false,
  8. ],
  9. ],
  10. ];

注解说明

@Controller

注释目标:类

表明一个类是控制器类

属性名称 说明
prefix 动作配置的访问地址前缀,如果动作配置的访问地址规则以/开始,则本属性无效

@Route

注释目标:方法

指定路由规则

属性名称 说明
url 请求地址规则。以/开头则忽视@Controller中的prefix支持代入{name}形式占位符,匹配出来的值可以作为参数传入动作
method 如果设置了method,则请求方法必须在method列表中才可以进到动作。支持字符串和数组。如:"GET"{"GET", "POST"}
domain 判断域名,只有符合条件才允许访问。支持字符串和数组,支持{name}形式占位符,可以作为参数传入动作
paramsGet 判断GET参数,只有符合条件才允许访问。可以是字符串或数组。id=100必须包含id,并且值为100id!=100id<>100必须包含id,并且值不为100id必须包含id参数!id必须不包含id参数["id" => "\d+"]支持正则
paramsPost 判断POST参数,用法同paramsGet
header 判断请求头,用法同paramsGet
requestMime 请求的mime类型判断判断请求头中的Content-Type中是否包含这些mime类型之一支持字符串和字符串数组
ignoreCase 忽略请求地址大小写null-取HttpRoute中默认值true-忽略大小写false-严格判断

@Action

注释目标:方法

表明一个方法是动作

属性:无


如下代码所示,一个最简单的控制器+路由注解代码。

  1. <?php
  2. namespace Test;
  3. use Imi\Controller\HttpController;
  4. use Imi\Server\Route\Annotation\Route;
  5. use Imi\Server\Route\Annotation\Action;
  6. use Imi\Server\Route\Annotation\Controller;
  7. /**
  8. * 一个简单的控制器
  9. * @Controller
  10. */
  11. class Index extends HttpController
  12. {
  13. /**
  14. * 一个动作
  15. * @Action
  16. * @Route(url="/")
  17. */
  18. public function index()
  19. {
  20. return $this->response->write('hello imi!');
  21. }
  22. }

访问地址:http://localhost:{port}/输出内容:

  1. hello imi!

配置

路由配置必须写在服务器配置文件中,如果你写在项目配置文件是无效的。

路由配置支持三种方式:传统、回调、路由回调

  1. <?php
  2. return [
  3. 'route' => [
  4. // 传统方式,直接指定控制器、方法、路由,和注解方式比较类似
  5. [
  6. 'controller' => \ImiDemo\HttpDemo\MainServer\Controller\Test::class,
  7. 'method' => 'index',
  8. 'route' => [
  9. 'url' => '/test',
  10. // 'method' => 'PUT',
  11. // 'method' => ['GET', 'POST'],
  12. // 'domain' => '{name}.xxx.com',
  13. ],
  14. ],
  15. // 回调方式,给callback指定一个callable类型
  16. [
  17. 'route' => [
  18. 'url' => '/callback1',
  19. ],
  20. 'callback' => function () {
  21. return RequestContext::get('response')->write('callback1');
  22. },
  23. ],
  24. // 路由回调方式,new RouteCallable(类名, 方法名)
  25. [
  26. 'route' => [
  27. 'url' => '/callback2',
  28. ],
  29. 'callback' => new RouteCallable('\Test', 'abc'),
  30. ],
  31. // 匹配URL,把interface代入到类、方法名中
  32. [
  33. 'controller' => '\ImiDemo\HttpDemo\MainServer\Controller\Test{$interface}',
  34. 'method' => '{$interface}',
  35. 'route' => [
  36. 'url' => '/test/{interface}',
  37. ],
  38. ],
  39. // 懒人免去写@Controller和@Action注解的麻烦
  40. [
  41. 'controller' => '\ImiDemo\HttpDemo\MainServer\Controller\{$controller}',
  42. 'method' => '{$action}',
  43. 'route' => [
  44. 'url' => '/{controller}/{action}',
  45. ],
  46. ],
  47. ]
  48. ];

获取当前路由解析结果 (routeResult)

  1. $routeResult = RequestContext::get('routeResult');

$routeResult 定义:

  1. /**
  2. * 路由配置项
  3. *
  4. * @var \Imi\Server\UdpServer\Route\RouteItem
  5. */
  6. public $routeItem;
  7. /**
  8. * 参数
  9. *
  10. * @var array
  11. */
  12. public $params;
  13. /**
  14. * 回调
  15. *
  16. * @var callable
  17. */
  18. public $callable;

$routeResult->routeItem 定义:

  1. /**
  2. * 注解
  3. *
  4. * @var \Imi\Server\Route\Annotation\Route
  5. */
  6. public $annotation;
  7. /**
  8. * 回调
  9. *
  10. * @var callable|\Imi\Server\Route\RouteCallable
  11. */
  12. public $callable;
  13. /**
  14. * 中间件列表
  15. *
  16. * @var array
  17. */
  18. public $middlewares = [];
  19. /**
  20. * WebSocket 配置
  21. *
  22. * @var array
  23. */
  24. public $wsConfig = [];
  25. /**
  26. * 其它配置项
  27. *
  28. * @var array
  29. */
  30. public $options;