ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] ### 组件说明 1. Lying只支持一种路由模式:rewrite,如果你的服务器并不能配置rewrite,且移步其他框架吧 2. rewrite 当你的web服务器支持rewrite,并且你按照Lying的[部署](deploy.md)章节设置了rewrite规则,你可以这样访问网站: ~~~ http://domain/module/controller/action/param/value ~~~ ### 配置选项 | 配置名 | 参数类型 | 可选 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | class | string | 是 | lying\service\Router | 不可更改 | | binding | bool | 是 | null | 默认路由是否绑定模块 | | module | string | 是 | index | 默认模块 | | controller | string | 是 | index | 默认控制器 | | action | string | 是 | index | 默认方法 | | suffix | string\|bool | 是 | false | 使用的后缀名 | | rule | array | 是 | [] | 路由规则 | | host | array | 是 | [] | 域名模块绑定 | ### 示例配置 * 路由配置对大小写敏感。 * 可选参数如果不需要都应该被注释或者设置成等同于false的值。 * 域名绑定模块里的参数如果不设置,会默认继承父级配置。 ~~~php 'router' => [ 'class' => 'lying\service\Router', //路由完整类名,可以不写,因为是核心组件 'binding' => true, //默认路由是否绑定模块 'module' => 'index', //默认模块,默认index 'controller' => 'index',//默认控制器,默认index 'action' => 'index', //默认方法,默认index 'suffix' => '.html', //使用的后缀名,默认空 'rule' => [ //路由规则 //如果binding为false,规则对应的路径应该为全部小写,并且是从[模块]开始写 //如果binding为true,规则对应的路径应该为全部小写,并且是从[控制器]开始写 //设置规则后原url失效;规则匹配是从上到下,匹配到了就不会继续下一条匹配 'blog/<id:\d+>/<name>$' => ['admin/blog/get', '.htm'], 'user/<name>/<id>$' => ['user/info/name'], 'yoyo' => ['index/index/index'], ], 'host' => [ //域名模块绑定 'api.lying.com' => [ //域名,域名绑定的`binding`参数固定为true 'module' => 'index', //域名绑定的模块,默认继承上述配置 'controller' => 'index',//默认控制器,默认继承上述配置 'action' => 'index', //默认方法,默认继承上述配置 'suffix' => '.js', //使用的后缀名,默认继承上述配置 'rule' => [ //路由规则,默认继承上述配置 //规则对应的路径应该为全部小写,并且是从[控制器]开始写 //设置规则后原url失效;规则匹配是从上到下,匹配到了就不会继续下一条匹配 'user/<id>$' => ['index/user', '.html'], ], ], ], ], ~~~ > binding配置项说明:binding为true的时候,默认路由绑定默认配置项的`module`配置,所以路由规则`rule`的形式应该是`'user/<id>$' => ['index/user']`,而不是`'blog/<id>$' => ['admin/index/user']` 看到这么一大堆配置是不是头大?我也很头大!只能用举栗子来说明了。 #### DEMO1 配置文件: ~~~php 'router' => [ ], ~~~ ~~~html http://domain 这时候访问的模块为`index`,控制器为`IndexCtrl`,方法为`index` ~~~ ~~~html http://domain/a/b/c 这时候访问的模块为`a`,控制器为`BCtrl`,方法为`c` ~~~ #### DEMO2 配置文件: ~~~php 'router' => [ 'module' => 'admin', 'controller' => 'user', 'action' => 'add', 'suffix' => '.html', ], ~~~ ~~~html http://domain/ //访问的模块为`admin`,控制器为`UserCtrl`,方法为`add` http://domain/user/name.html //访问的模块为`user`,控制器为`NameCtrl`,方法为`add` http://domain/index/post/del/id/1.html //访问的模块为`index`,控制器为`PostCtrl`,方法为`del`,并且带有一个GET参数`id`,值为1 http://domain/user/ //访问的模块为`user`,控制器为`UserCtrl`,方法为`add` ~~~ #### 小结 > * 如果设置了module、controller、action,只有在路由缺省模块、控制器、方法的时候,才会使用到默认模块、默认控制器和默认方法;如果没有设置module、controller、action,那么默认分别是index、index、index。 > * 如果配置了suffix选项,那么可以带上后缀访问,也可以不带;如果没有配置后缀,那么带上后缀访问就会报404。 ### 路由规则 先记住下面几点: * 如果模块目录为`wechatApi`,那么模块在路由和配置中的表现为`wechat-api`。 * 如果控制器为`UserListCtrl`,那么控制器在路由和配置中的表现为`user-list`。 * 如果方法为`delUser`,那么方法在路由和配置中的表现为`del-user`。 好了,我们开始讲路由规则: #### DEMO1 配置文件: ~~~php 'router' => [ 'rule' => [ 'user'=>['index/index/name'], ], ], ~~~ ~~~html http://domain/user/ 实际上你访问到的是 http://domain/index/index/name/ ~~~ ~~~html http://domain/user/sex/1/ 实际上你访问到的是 http://domain/index/index/name/sex/1/ 你可以使用$_GET['sex']来获取到参数 ~~~ > 如果你刚好有一个模块名为`user`,那么你将不能通过`http://domain/user/`访问`user`模块,所以设置路由规则的时候请注意。 #### DEMO2 配置文件: ~~~php 'router' => [ 'rule' => [ 'user/<id>'=>['index/index/name'], ], ], ~~~ ~~~html http://domain/user/1/ 实际上你访问到的是 http://domain/index/index/name/id/1/ 你可以使用$_GET['id']来获取到参数 ~~~ #### DEMO3 配置文件: ~~~php 'router' => [ 'rule' => [ 'user/<id:^\d+$>'=>['index/index/name'], ], ], ~~~ ~~~html http://domain/user/1/ 实际上你访问到的是 http://domain/index/index/name/id/1/ 你可以使用$_GET['id']来获取到参数 ~~~ ~~~html http://domain/user/1/name/lying/ 实际上你访问到的是 http://domain/index/index/name/id/1/name/lying/ 你可以使用$_GET['id']、$_GET['name']来获取到参数 ~~~ ~~~html http://domain/user/abc/ 因为`abc`不匹配正则/^\d+$/,这时候尝试访问user模块下的AbcCtrl控制器,如果不存在则报404错误。 ~~~ #### DEMO4 配置文件: ~~~php 'router' => [ 'rule' => [ 'user/<id:^\d+$>$'=>['index/index/name', '.xml'], ], ], ~~~ ~~~html http://domain/user/1.xml 实际上你访问到的是 http://domain/index/index/name/id/1/ 你可以使用$_GET['id']来获取到参数id ~~~ ~~~html http://domain/user/1/name/lying.xml 这条路径不匹配规则,因为规则定义path只到id就结束了,注意`$`符号 所以实际上你访问到的是 http://domain/user/1/name/lying.xml 就会报404错误啦 ~~~ ~~~html http://domain/user/123/ 因为`abc`不匹配后缀`.xml`,这时候报404错误。 ~~~ #### 小结 > * 为路由参数设置正则,只要有一个正则不匹配就认为不匹配。 > * 不是所有的参数都必须设置匹配规则。 > * 如果设置了参数,参数就必须存在才能匹配到路由。 > * 如果设置了多个路由,则按照从上到下的顺序匹配,匹配到了就不会进行下一条路由规则的匹配。 > * 如果所有的规则都不匹配,就按照`模块/控制器/方法`来解析路由;binding模式下就按照`控制器/方法`来解析路由。 ### 调用方式 ~~~php \Lying::$maker->get('router'); \Lying::$maker->router(); \Lying::$maker->router; ~~~ ### URL生成 #### DEMO 配置文件: ~~~php 'router' => [ 'module' => 'index', 'controller' => 'user', 'action' => 'name', 'suffix' => '.html', 'rule' => [ 'user' => ['index/index/name'], 'admin/<id>' => ['admin/money/count', '.xml'], 'qq/<num:\d+>$' => ['qq/info/get-num', '.js'], ], ], ~~~ 此次请求路径为: ~~~html http://domain/ ~~~ ~~~php 1. \Lying::$maker->router->createUrl('sex'); http://domain/index/user/sex.html 2. \Lying::$maker->router->createUrl('money/count'); http://domain/index/money/count.html 3. \Lying::$maker->router->createUrl('user/money/count'); http://domain/user/money/count.html 4. \Lying::$maker->router->createUrl('index/name'); http://domain/user.html 5. \Lying::$maker->router->createUrl('index/index/name'); http://domain/user.html 6. \Lying::$maker->router->createUrl('admin/money/count', ['id'=>1]); http://domain/admin/1.xml 7. \Lying::$maker->router->createUrl('admin/money/count'); http://domain/admin/money/count.html 8. \Lying::$maker->router->createUrl('qq/num/stat', ['name'=>'qq'], false, true); /qq/num/stat.html?name=qq 9. \Lying::$maker->router()->createUrl('admin/money/count', ['id'=>1, 'name'=>'lying']); http://domain/admin/1/name/lying.xml 10. \Lying::$maker->router()->createUrl('qq/info/get-num', ['num'=>296399959, 'name'=>'lying']); http://domain/qq/296399959.js?name=lying ~~~ #### 路由生成规则 路由判断: * `index => '当前模块/当前控制器/index'` * `index/name => '当前模块/index/name'` * `admin/user/list => 'admin/user/list'` * `/admin/user => '/admin/user'` * `/admin/user.html => '/admin/user.html'` 规则匹配: * 如果在rule上有定义要生成的路径url,并且参数个数刚好、参数格式匹配的话,就会反解析成路由规则所定义的url。当然,如果你的参数比路由设置上的多了,这样并不影响路由匹配,并且还是能获取GET参数。 ### 方法列表 ~~~php /** * 返回此次请求的模块ID * @return string */ public function module(); ~~~ ***** ~~~php /** * 返回此次请求的控制器ID * @return string */ public function controller(); ~~~ ***** ~~~php /** * 返回此次请求的方法ID * @return string */ public function action(); ~~~ ***** ~~~php /** * URL生成 * ```php * 路径[/index/blog/info],生成[/index/blog/info],使用此形式的时候请注意参数匹配,并且不会路由反解析 * 路径[post],生成[当前模块/当前控制器/post] * 路径[post/index],生成[当前模块/post/index] * 路径[admin/post/index],生成[admin/post/index],注意:此用法在模块绑定中会变成[post/index],模块绑定模式下,只需要最多到控制器就行 * ``` * @param string $path 路径 * @param array $params 参数数组,不合法的参数将被剔除,如果有路由规则,参数中必须包含rule中的参数才能反解析 * @param bool $host 是否携带完整域名,包含协议头,默认是 * @param bool $normal 是否把参数设置成?a=1&b=2,默认否,优先pathinfo * @return string 返回生成的URL */ public function createUrl($path, array $params = [], $host = true, $normal = false); ~~~