🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# **路由:** ThinkPHP5.0的路由规则定义是从根目录开始,而不是基于模块名的。 application/route.php注册   然后访问变成`http://serverName/new/5` ~~~ use think\Route; // 注册路由到index模块的News控制器的read操作 Route::rule('new/:id','index/News/read'); ~~~ ## **参数配置:** ``` // 是否开启路由 'url_route_on' => true, // 路由配置文件(支持配置多个) 'route_config_file' => ['route'], // 路由使用完整匹配 'route_complete_match' => false, // 是否强制使用路由    为true的话必须要为每个url配置路由才能访问哦 所以才开发阶段可以false 这样原url和路由url都可以访问到 'url_route_must' => false, ``` 路由模式:**普通**、**强制**和**混合**模式 **1、普通模式:** ~~~ //配置文件 关闭路由,完全使用默认的PATH_INFO方式URL 'url_route_on' => false, ~~~ 路由关闭后,不会解析任何路由规则,采用默认的`PATH_INFO`模式访问URL: ~~~ http://serverName/index.php/module/controller/action/param/value/... ~~~ 关闭路由后的普通模式任然可以通过操作方法的 **[参数绑定](https://www.cnblogs.com/lichihua/p/10405130.html)**、控制器和空操作等特性实现url地址的简化 可以设置`url_param_type`配置参数来改变pathinfo模式下面的参数获取方式,默认是按名称成对解析,支持按照顺序解析变量,只需要更改为: ~~~ // 按照顺序解析变量 'url_param_type' => 1, ~~~ **2、强制模式:** ~~~ //配置文件如下配置 'url_route_on' => true, 'url_route_must' => true, //这种方式下面必须严格给每一个访问地址定义路由规则(包括首页),否则将抛出异常。 //首页的路由规则采用/定义即可,例如下面把网站首页路由输出Hello,world! Route::get('/',function(){ return 'Hello,world!'; }); ~~~ **3、混合模式:** ~~~ //开启路由,并使用路由定义+默认PATH_INFO方式的混合 //配置如下 'url_route_on' => true, 'url_route_must'=> false, //该方式下面,只需要对需要定义路由规则的访问地址定义路由规则,其它的仍然按照第一种普通模式的PATH_INFO模式访问URL ~~~ 注册方式:**动态注册**和**路由配置**两种方式 >[danger]由于检测机制问题,**动态注册的性能比路由配置要高一些**,尤其是多种请求类型混合定义的时候。 **1、动态注册:** 路由定义采用`\think\Route`类的`rule`方法注册,通常是在应用的路由配置文件`application/route.php`进行注册,格式是 >[info]### **Route::rule('路由表达式','路由地址','请求类型','路由参数(数组)','变量规则(数组)');** 请求类型不指定的话默认为任何请求类型包含(GET、POST、PUT、DELETE、*表示任何其他请求) ~~~ 单个注册: Route::rule('路由规则表达式','路由地址','请求类型','路由参数(数组)','变量规则(数组)'); 例子: Route::rule( 'theme/:id/[:name]', 'home/Goods/theme', 'GET', //路由参数 [ 'method'=>'POST|GET|PUT',//请求类型检测 'ext'=>'shtml|html|php',//检测是shtml|html|php这三个后缀的请求就通过 'deny_ext'=>'jpg|png|gif',//URL禁止后缀检测,这里禁止检测jpg|png|gif者三个后缀 'domain'=>'news.thinkphp.cn',//子域名检测则直接news就行'domain'=>'news'] 'https'=>true,//检测是否https请求 'before_behavior'=>'\app\index\behavior\UserCheck',//前置行为(检测) 'after_behavior'=>'\app\index\behavior\ReadInfo',//后置行为(执行) 'callback'=>'my_check_fun',//自定义检测方法 'merge_extra_vars'=>true,//合并额外参数 'cache'=>3600,//请求缓存V5.0.1+ 'bind_model'=>['User','name'],//绑定模型V5.0.1+ 'param_depr'=>'',//路由参数分隔符V5.0.2+ 'ajax'=>true,//V5.0.2+ 'pjax'=>true,//V5.0.2+ ], ['name'=>'\w+','id'=>'\d+'] ); 批量注册: Route::rule( [ '路由规则表达式1'=>'路由地址和参数', '路由规则表达式2'=>['路由地址和参数','路由参数(数组)','变量规则(数组)'] ], '', '请求类型', '路由参数(数组)', '变量规则' ); //批量注册例子 Route::rule( [ 'new/:id' => 'News/read', 'blog/:id' => ['Blog/update',['ext'=>'shtml'],['id'=>'\d{4}'] ], ], '', 'GET', ['ext'=>'html'], ['id'=>'\d+'] ); ~~~ ### **路由规则表达式** 通常包含静态地址和动态地址,或者两种地址的结合,例如下面都属于有效的规则表达式: ~~~ Route::rule('/', 'index'); // 首页访问路由 Route::rule('my', 'Member/myinfo'); // 静态地址路由 Route::rule('blog/:id', 'Blog/read'); // 静态地址和动态地址结合 Route::rule('new/:year/:month/:day', 'News/read'); // 静态地址和动态地址结合 Route::rule(':user/:blog_id', 'Blog/read'); // 全动态地址 //当控制器文件不再controler文件夹下而是在controller子文件夹下时我们定义路由地址格式为\[子文件名.  控制器名\] //controller/v1/Banner.php 访问为:http://www.localhost/api/v1/banner/1 Route::get("api/v1/banner/:id","api/v1.Banner/getBanner"); //下面是动态调用(如不同版本) Route::get("api/:version/banner/:id","api/:version.Banner/getBanner"); //当前新品 Route::get("api/:version/product/recent","api/:version.Product/getRecent"); ~~~ ### **路由地址:** ~~~ 1、路由到模块/控制器/操作:'[模块/控制器/]操作?额外参数1=值1&额外参数2=值2...' // 路由到默认或者用define('BIND_MODULE','index');绑定的模块 'blog/:id'=>'blog/read', // 路由到admin模块 'blog/:id'=>'admin/blog/read', //支持多级控制器,路由到index/controller/group/Blog 'blog/:id'=>'index/group.blog/read', //支持路由到动态的模块、控制器或者操作 // action变量的值作为操作方法传入 ':action/blog/:id' => 'index/blog/:action' // 变量传入index模块的控制器和操作方法 ':c/:a'=> 'index/:c/:a' //额外参数`status`和`app_id`参数都是URL里面不存在的,属于隐式传值,当然并不一定需要用到,只是在需要的时候可以使用。 'blog/:id'=>'blog/read?status=1&app_id=5', 2、路由到操作方法: @[模块/控制器/]操作 //区别是直接执行某个控制器类的方法,而不需要去解析**模块/控制器/操作**这些,同时也不会去初始化模块 //前者走模块初始化的 这个是直接调用控制器类 性能好点 //直接执行Loader::action('index/blog/read');相当于直接调用 \app\\index\controller\blog类的read方法。 'blog/:id'=>'@index/blog/read', 3、路由到类的方法 动态:\完整的类命名空间\类名@方法名 静态:\完整的类命名空间\类名::方法名 // \app\index\service\Blog类的read方法 'blog/:id'=>'\app\index\service\Blog@read', 'blog/:id'=>'\app\index\service\Blog::read',//这个read是静态方法 'blog/:id'=>'\app\index\service\Blog::read?status=1',//这个read是静态方法 4、路由到重定向地址:'外部地址'(默认301重定向) 或者 \['外部地址','重定向代码'\] 必须以“/”或者http开头 'blog/:id'=>'/blog/read/id/:id' // 表示当前网站(可能是http://thinkphp.cn )的 blog/123地址 // 会直接重定向到http://blog.thinkphp.cn/read/123。 'blog/:id'=>'http://blog.thinkphp.cn/read/:id' ~~~ **路由地址参数可选定义** 变量用 [ ] 包含起来后就表示该变量是路由匹配的可选变量 ~~~ Route::get('blog/:year/[:month]','Blog/archive'); 下面的URL访问地址都可以被正确的路由匹配: http://serverName/index.php/blog/2015 http://serverName/index.php/blog/2015/12 ~~~ ### **路由参数** 路由参数以数组的形式出现,他们都是可选的,根据实际情况组合 ``` 'method'=>'POST|GET|PUT',//请求类型检测 'ext'=>'shtml|html|php',//检测是shtml|html|php这三个后缀的请求就通过 'deny_ext'=>'jpg|png|gif',//URL禁止后缀检测,这里禁止检测jpg|png|gif者三个后缀 'domain'=>'news.thinkphp.cn',//子域名检测则直接news就行'domain'=>'news'] 'https'=>true,//检测是否https请求 'before_behavior'=>'\app\index\behavior\UserCheck',//前置行为(检测) 'after_behavior'=>'\app\index\behavior\ReadInfo',//后置行为(执行) 'callback'=>'my_check_fun',//自定义检测方法 'merge_extra_vars'=>true,//合并额外参数 'cache'=>3600,//请求缓存V5.0.1+ 'bind_model'=>['User','name'],//绑定模型V5.0.1+ 'param_depr'=>'',//路由参数分隔符V5.0.2+ 'ajax'=>true,//V5.0.2+ 'pjax'=>true,//V5.0.2+ ``` ### **变量规则** ### 设置全局变量规则,全部路由有效: ~~~ 全局变量规则,作用于全部路由 // 设置name变量规则(采用正则定义) Route::pattern('name','\w+'); // 支持批量添加 Route::pattern([ 'name' => '\w+', 'id' => '\d+', ]); 局部变量规则,仅在当前路由有效 // 定义GET请求路由规则 并设置name变量规则 Route::get('new/:name','News/read',[],['name'=>'\w+']); ~~~ ### **请求类型** 默认支持所有的请求类型,可单独设置,多个用|分隔 ~~~ //如果要定义get和post请求支持的路由规则,也可以用: Route::rule('new/:id','News/read','GET|POST'); ~~~ 不同的请求类型定义路由规则的简化方法:请求类型参数必须大写 ~~~ Route::get('new/:id','News/read'); // 定义GET请求路由规则 Route::post('new/:id','News/update'); // 定义POST请求路由规则 Route::put('new/:id','News/update'); // 定义PUT请求路由规则 Route::delete('new/:id','News/delete'); // 定义DELETE请求路由规则 Route::any('new/:id','News/read'); // 所有请求都支持的路由规则 ~~~ ## **路由标志:设置一个唯一的用于url生成的字符** ~~~ // 注册路由到index模块的News控制器的read操作 Route::name('new_read')->rule('new/:id','index/News/read'); //生成路由地址的时候就可以使用 url('new_read',['id'=>10]); //如果不定义路由标识的话,使用下面的方式生成 url('index/News/read',['id'=>10]); V5.1.6+ 版本开始,路由标识的用法调整,原来的用法: // 注册路由到index模块的News控制器的read操作 Route::name('new_read')->rule('new/:id','index/News/read'); 需要改为: // 注册路由到index模块的News控制器的read操作 Route::rule('new/:id','index/News/read')->name('new_read'); 因为后者更符合语义。 ~~~ ## **路由别名:Route::alias('别名','模型/控制器');** ~~~ use think\Route; Route::alias('home','index/index'); Route::alias('admin','admin/index'); 或者: return [ '__alias__' => [ 'home' => 'index/index', 'admin'=> 'admin/index' ], ]; ~~~ ## **资源路由** ~~~ //注册资源路由(资源路由会自动注册7个路由规则分别对应下面新建的这几个方法) //动态注册 Route::resource('user','index/user'); //或者路由配置 return [ // 定义资源路由 '__rest__'=>[ // 指向index模块的User控制器 'user'=>'index/user', ], // 定义普通路由 'hello/:id'=>'index/hello', ]; //在指向index模块的User控制器新建index()、create($id)、save、read($id)、eidit($id)、update($id)、delete($id)方法 URL访问: index:访问用户列表【GET】index方法可省略 http://serverName/user/ create:创建用户页面【GET】 http://serverName/user/create save:创建用户【POST】 http://serverName/user/ read:获取单个用户信息【GET】 http://serverName/user/128 edit:获取编辑数据(更新页面)【GET】 http://serverName/user/128/edit update:更新单个用户(实际执行编辑更新)【PUT】 http://serverName/user/128 delete:删除单个用户【DELETE】 http://serverName/user/128 ~~~ 将参数$id定义为$blog_id ~~~ Route::resource('user','index/user',['var'=>['user'=>'user_id']]); 对应方法变为 index()、create($user_id)、save、read($user_id)、eidit($user_id)、update($user_id)、delete($user_id)方法 ~~~ 也可以在定义资源路由的时候限定执行的方法(标识),例如: ~~~ // 只允许index read edit update 四个操作 Route::resource('user','index/user',['only'=>['index','read','edit','update']]); // 排除index和delete操作 Route::resource('user','index/user',['except'=>['index','delete']]); ~~~ 资源路由的标识不可更改,但生成的路由规则和对应操作方法可以修改。 数组第一个参数:请求类型 数组第二个参数:请求规则 数组第三个参数:路由标识对应的控制器方法请求 ~~~ // 修改之前看下默认的REST路由操作方法定义 private static $rest = [ 'index' => ['get', '', 'index'], 'create' => ['get', '/create', 'create'], 'edit' => ['get', '/:id/edit', 'edit'], 'read' => ['get', '/:id', 'read'], 'save' => ['post', '', 'save'], 'update' => ['put', '/:id', 'update'], 'delete' => ['delete', '/:id', 'delete'], ]; Route::rest('create',['GET', '/add','add']); //支持批量更改 Route::rest([ 'index'=>['GET','','front'], 'create'=>['GET', '/add','add'] 'save' => ['POST', '', 'store'], 'update' => ['PUT', '/:id', 'save'], 'delete' => ['DELETE', '/:id', 'destory'], ]); URL访问: index:访问用户列表【GET】访问的是front方法而不是index方法 http://serverName/user create:创建用户页面【GET】 http://serverName/user/add save:创建用户【POST】访问的是store方法了而不是默认的save方法 http://serverName/user/ read:获取单个用户信息【GET】 http://serverName/user/128 edit:获取编辑数据(更新页面)【GET】 http://serverName/user/128/edit update:更新单个用户(实际执行编辑更新)【PUT】访问的是save方法而不是update方法 http://serverName/user/128 delete:删除单个用户【DELETE】访问的是destory方法而不是delete方法 http://serverName/user/128 ~~~ ### 资源嵌套 支持资源路由的嵌套,例如: ~~~ Route::resource('blog.comment','index/comment'); ~~~ 就可以访问如下地址: ~~~ http://serverName/blog/128/comment/32 http://serverName/blog/128/comment/32/edit ~~~ 生成的路由规则分别是: ~~~ blog/:blog_id/comment/:id blog/:blog_id/comment/:id/edit ~~~ Comment控制器对应的操作方法如下: ~~~ namespace app\index\controller; class Comment{ public function edit($id,$blog_id){ } } ~~~ edit方法中的参数顺序可以随意,但参数名称必须满足定义要求。 如果需要改变其中的变量名,可以使用: ~~~ // 更改嵌套资源路由的blog资源的资源变量名为blogId Route::resource('blog.comment','index/comment',['var'=>['blog'=>'blogId']]); ~~~ Comment控制器对应的操作方法改变为: ~~~ namespace app\index\controller; class Comment{ public function edit($id,$blogId) { } } ~~~ `Route::resource('blog','index/blog');`路由规则: | 标识 | 请求类型 | 生成路由规则 | 对应操作方法(默认) | url地址| | --- | --- | --- | --- | --- | | index | GET | `blog` | index |http://serverName/blog| | create | GET | `blog/create` | create($id) | http://serverName/blog/create| | save | POST | `blog` | save | http://serverName/blog/| | read | GET | `blog/:id` | read($id) | http://serverName/blog/128| | edit | GET | `blog/:id/edit` | edit($id) | http://serverName/blog/128/edit| | update | PUT | `blog/:id` | update($id) |http://serverName/blog/128| | delete | DELETE | `blog/:id` | delete($id) |http://serverName/blog/128| 资源路由的嵌套`Route::resource('blog.comment','index/comment'` 会对应index模块的comment控制器 路由规则 | 标识 | 请求类型 | 生成路由规则 | 对应操作方法(默认) |url地址| | --- | --- | --- | --- | --- | | index | GET | `blog` | index |http://serverName/blog| | create | GET | `blog/create` | create($id) | http://serverName/blog/create| | save | POST | `blog` | save | http://serverName/blog/| | read | GET | blog/:blog_id/comment/:id | read($id) | http://serverName/blog/128| | edit | GET | blog/:blog_id/comment/:id/edit | edit($id,$blog_id) | http://serverName/blog/128/comment/32/edit| | update | PUT | blog/:blog_id/comment/:id | update($id) |http://serverName/blog/128| | delete | DELETE | blog/:blog_id/comment/:id | delete($id) |http://serverName/blog/128| 参数的顺序随便 同理也可以更改参数变量名 ~~~ // 更改嵌套资源路由的blog资源的资源变量名为blogId Route::resource('blog.comment','index/comment',['var'=>['blog'=>'blogId']]); 修改后方法变为:edit($id,$blogId)或edit($blogId, $id) ~~~ ## **快捷路由** ``` //快捷路由 Route::controller('user','模块/控制器'); // 给User控制器设置快捷路由 控制器方法为 请求类型+方法名 如getInfo()与postInfo() // get http://localhost/user/phone post http://localhost/user/info Route::controller('user','index/User'); ``` ## **路由别名** 不支持变量类型和路由条件判断,单纯只是为了缩短URL地址 不推荐 ~~~ //我们希望使用user可以访问Home模块的User控制器的所有操作 那么我么定义别名为 Route::alias('user','home/User'); //或者 return [ '__alias__' => [ 'user' => 'home/User', //'user' => ['home/User',['ext'=>'html']], ], ]; //路由别名可以指向任意一个有效的路由地址,例如下面指向一个类 // user 路由别名指向 User控制器类 Route::alias('user','\app\index\controller\User'); // user 别名路由到 index/user 控制器 Route::alias('user','index/user',[ 'ext'=>'html',//设置路由条件 'allow'=>'index,read,edit,delete',//白名单 'except'=>'save,delete',//黑名单 'method'=>['index'=>'GET','save'=>'POST','delete'=>'DELETE'],//设置操作方法的请求类型 ]); ~~~ ## **路由分组** ~~~ Route::rule( [ 'blog/:id' => ['Blog/read', ['method' => 'get'], ['id' => '\d+']], 'blog/:name' => ['Blog/read', ['method' => 'post']], ], ); //可以合并到一个blog分组 Route::rule( [ '[blog]' => [ ':id' => ['Blog/read', ['method' => 'get'], ['id' => '\d+']], ':name' => ['Blog/read', ['method' => 'post']], ], ], ); ~~~ 也可以使用group方法进行分组 ``` //路由分组 允许把相同前缀的路由定义合并分组 Route::group('blog',[ ':id' => ['Blog/read', ['method' => 'get'], ['id' => '\d+']], ':name' => ['Blog/read', ['method' => 'post']], ],['method'=>'get','ext'=>'html']); ``` 支持使用闭包方式注册路由分组,例如: ~~~ Route::group('blog',function(){ Route::any(':id','blog/read',[],['id'=>'\d+']); Route::any(':name','blog/read',[],['name'=>'\w+']); },['method'=>'get','ext'=>'html']); ~~~ 如果仅仅是用于对一些路由规则设置一些公共的路由参数,也可以使用: ~~~ Route::group(['method'=>'get','ext'=>'html'],function(){ Route::any('blog/:id','blog/read',[],['id'=>'\d+']); Route::any('blog/:name','blog/read',[],['name'=>'\w+']); }); ~~~ 路由分组支持嵌套,例如: ~~~ Route::group(['method'=>'get','ext'=>'html'],function(){ Route::group('blog',function(){ Route::any('blog/:id','blog/read',[],['id'=>'\d+']); Route::any('blog/:name','blog/read',[],['name'=>'\w+']); } }); ~~~ ## **MISS路由** 如果希望在没有匹配到所有的路由规则后执行一条设定的路由,可以使用`MISS`路由功能,只需要在路由配置文件中定义: ~~~ return [ 'new/:id' => 'News/read', 'blog/:id' => ['Blog/update',['method' => 'post|put'], ['id' => '\d+']], '__miss__' => 'public/miss', ]; ~~~ 或者使用`miss`方法注册路由 ~~~ Route::miss('public/miss'); ~~~ 当没有匹配到所有的路由规则后,会路由到`public/miss`路由地址。 ## 分组MISS路由 分组支持独立的`MISS`路由,例如如下定义: ~~~ return [ '[blog]' => [ 'edit/:id' => ['Blog/edit',['method' => 'get'], ['id' => '\d+']], ':id' => ['Blog/read',['method' => 'get'], ['id' => '\d+']], '__miss__' => 'blog/miss', ], 'new/:id' => 'News/read', '__miss__' => 'public/miss', ]; ~~~ 如果使用`group`方法注册路由的话,可以使用下面的方式: ~~~ Route::group('blog',function(){ Route::rule(':id','blog/read',[],['id'=>'\d+']); Route::rule(':name','blog/read',[],['name'=>'\w+']); Route::miss('blog/miss'); },['method'=>'get','ext'=>'html']); ~~~ ## **闭包定义** 我们可以使用闭包的方式定义一些特殊需求的路由,而不需要执行控制器的操作方法了,例如: ~~~ Route::get('hello',function(){ return 'hello,world!'; }); //参数传递,规则路由中定义的动态变量的名称 就是闭包函数中的参数名称,不分次序。 Route::get('hello/:name',function($name){ return 'Hello,'.$name; }); 因此,如果我们访问的URL地址是:http://serverName/hello/thinkphp 则浏览器输出的结果是:Hello,thinkphp ~~~ ## **路由绑定** ### **绑定到模块/控制器/操作** 把当前的URL绑定到模块/控制器/操作,最多支持绑定到操作级别,例如在路由配置文件中添加: ~~~ // 绑定当前的URL到 index模块 Route::bind('index'); // 绑定当前的URL到 index模块的blog控制器 Route::bind('index/blog'); // 绑定当前的URL到 index模块的blog控制器的read操作 Route::bind('index/blog/read'); ~~~ 例子: ``` http://serverName/index/blog/read/id/5 如果定义了路由 Route::get('index/blog/:id','index/blog/read'); 访问路径变为 http://serverName/index/blog/5 假如我们绑定到了index模块的blog控制器 Route::bind('index/blog'); 那么访问URL就变成了 http://serverName/5 ``` ~~~ // 绑定命名空间 Route::bind('\app\index\controller','namespace');//通过http://serverName/blog/read/id/5就可以直接访问 \app\index\controller\Blog类的read方法。 // 绑定到类 Route::bind('\app\index\controller\Blog','class');//通过http://serverName/read/id/5就可以直接访问 \app\index\controller\Blog类的read方法。 //入口文件绑定 // 复制一份入口文件添加define('BIND_MODULE','admin'); 命名为demo.php 我们访问这个demo.php就访问的是admin模块 // 自动入口绑定 // 配置文件开启入口文件自动绑定模块 'auto_bind_module' => true, //复制一份index.php 改名为demo.php 访问index.php是访问index模块 访问的demo.php则访问得是demo模块 ~~~ ## 模型绑定(`V5.0.1`) 路由规则和分组支持绑定模型数据,例如: ~~~ Route::rule('hello/:id','index/index/hello','GET',[ 'ext' => 'html', 'bind_model' => [ 'user' => '\app\index\model\User', ], ]); ~~~ 会自动给当前路由绑定`id`为 当前路由变量值的`User`模型数据。 可以定义模型数据的查询条件,例如: ~~~ Route::rule('hello/:name/:id','index/index/hello','GET',[ 'ext' => 'html', 'bind_model' => [ 'user' => ['\app\index\model\User','id&name'] ], ]); ~~~ 表示查询`id`和`name`的值等于当前路由变量的模型数据。 也可以使用闭包来返回模型对象数据 ~~~ Route::rule('hello/:id','index/index/hello','GET',[ 'ext' => 'html', 'bind_model' => [ 'user' => function($param){ $model = new \app\index\model\User; return $model->where($param)->find(); } ], ]); ~~~ 闭包函数的参数就是当前请求的URL变量信息。 在控制器中可以通过下面的代码或者使用依赖注入获取: ~~~ request()->user; ~~~ > 绑定的模型可以直接在控制器的架构方法或者操作方法中自动注入,具体可以参考请求章节的依赖注入。 ## **域名路由** 全一点的例子 ~~~ use think\Route; // 注册路由到index模块的News控制器的read操作 Route::rule('show/:id','test/Index/index');//id必须 Route::rule('show/[:id]','test/Index/index');//id可选 Route::rule('new/:id','News/update','POST');//第三个参数为空则表示接受所有的请求类型的参数 //完全匹配 Route::rule('show/:id$','test/Index/index');//只有http://www.admindemo2.com/show/2才能访问而去掉$的话http://www.admindemo2.com/show/2/3/tom/...也能通过 //全局完全匹配(开启全局完全匹配后所有的都不用再加$) //配置文件添加 //'route_complete_match' => true,//开启路由定义的全局完全匹配 //当开启全局完全匹配的时候,如果个别路由不需要使用完整匹配,可以添加路由参数覆盖定义: //Route::rule('new/:id','News/read','GET|POST',['complete_match' => false]); Route::get('routeget','test/Index/routeGet'); // 定义GET请求路由规则,同Route::rule('routeget','test/Index/routeGet','GET');//只接受get的请求 Route::get('routeget/:id','test/Index/routeGet'); // 同//Route::rule('routeget/:id','test/Index/routeGet','GET');//只接受get的请求 //注意: Route::get('routeget','test/Index/routeGet');与Route::get('routeget/:id','test/Index/routeGet');同时定义相当于Route::get('routeget/[:id]]','test/Index/routeGet');文档说明:注册多个路由规则后,系统会依次遍历注册过的满足请求类型的路由规则,一旦匹配到正确的路由规则后则开始调用控制器的操作方法,后续规则就不再检测 所以为了避免冲突最好将优先级高的放在最前面(比如单个设置的变量规则和路由规则放前面,全局的放在最后面) Route::rule('routepost','test/Index/routePost','POST');//post的请求才能接受 Route::rule('routepostorget','test/Index/routePostOrGet','POST|GET');//只接受get和post请求,其他一律不接受 // 定义new路由命名标识 Route::rule(['name','routenameflag/:id'],'test/Index/routeNameFlag'); //http://www.admindemo2.com/routenmeflag/1 //{:url('name',['id'=>1])} Route::rule(['name2','routenameflag2/'],'test/Index/routeNameFlag2');//第二个参数有没有/都无所谓 //http://www.admindemo2.com/routenmeflag2 or //http://www.admindemo2.com/routenmeflag2/ //{:url('name2')} Route::rule(['name3','routenameflag3/[:id]'],'test/Index/routeNameFlag3'); //http://www.admindemo2.com/routenmeflag3 or //http://www.admindemo2.com/routenmeflag3/1 //{:url('name3')} or //{:url('name',['id'=>1])} //批量注册: Route::rule(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']); Route::get(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']); /* Route::rule('路由表达式','路由地址','请求类型','路由参数(数组)','变量规则(数组)'); Route::rule( [ '路由规则1'=>'路由地址和参数', '路由规则2'=>['路由地址和参数','匹配参数(数组)','变量规则(数组)'] ], '', '请求类型', '匹配参数(数组)', '变量规则' ); */ Route::rule( [ 'new/:id' => 'News/read', 'blog/:id' => ['Blog/update',['ext'=>'shtml'],['id'=>'\d{4}']], ':action/blog/:id' => 'index/blog/:action',// action变量的值作为操作方法传入 ':c/:a'=> 'index/:c/:a',// 变量传入index模块的控制器和操作方法 ], '', 'GET', ['ext'=>'html'], ['id'=>'\d+'] ); //变量规则 //1、设置单个路由全局的变量规则 Route::rule('new/:tittle','News/update'); // 设置tittle变量规则(采用正则定义) Route::pattern('name','\w+'); //2、批量设置路由全局规则 Route::rule('new/:tittle','News/update'); Route::rule('banner/:id','home/Goods/banner'); Route::pattern([ 'tittle' => '\w+', 'id' => '\d+', ]); //3、设置局部变量规则,仅在当前路由有效 Route::get('new/:name','News/read',[],['name'=>'\w+']); //4、完整URL规则 Route::get('allurl/:catergory','test/Index/allUrl',[],['__url__'=>'allurl\/[A-Za-z0-9]{1,}$']);//id必须 //组合变量 //http://www.admindemo2.com/item-sb or http://www.admindemo2.com/item-sb555 or http://www.admindemo2.com/item-sb555a /*Route::get('item-<name><id?>','test/Index/product',[],['name'=>'\w+','id'=>'\d+']);*/ // http://www.admindemo2.com/item-sb-555 Route::get('item-<name>-<id>','test/Index/product',[],['name'=>'\w+','id'=>'\d+']); Route::rule('路由表达式','路由地址','请求类型','路由参数(数组)','变量规则(数组)'); 例子: Route::rule( 'theme/:id/[:name]', 'home/Goods/theme',//路由地址 'GET', //路由参数 [ 'method'=>'POST|GET|PUT',//请求类型检测 'ext'=>'shtml|html|php',//检测是shtml|html|php这三个后缀的请求就通过 'deny_ext'=>'jpg|png|gif',//URL禁止后缀检测,这里禁止检测jpg|png|gif者三个后缀 'domain'=>'news.thinkphp.cn',//子域名检测则直接news就行'domain'=>'news'] 'https'=>true,//检测是否https请求 'before_behavior'=>'\app\index\behavior\UserCheck',//前置行为(检测) 'after_behavior'=>'\app\index\behavior\ReadInfo',//后置行为(执行) 'callback'=>'my_check_fun',//自定义检测方法 'merge_extra_vars'=>true,//合并额外参数 'cache'=>3600,//请求缓存V5.0.1+ 'bind_model'=>['User','name'],//绑定模型V5.0.1+ 'param_depr'=>'',//路由参数分隔符V5.0.2+ 'ajax'=>true,//V5.0.2+ 'pjax'=>true,//V5.0.2+ ], ['name'=>'\w+','id'=>'\d+'] ); //路由地址 //1、额外参数: Route::get('extraparams/:id','test/Index/extraParam?status=1&app_id=5'); // http://www.admindemo2.com/extraparams/2/3 访问 // Request::instance()->route()能获取到id、status、app_id //2 路由到模块/控制器 [模块/控制器/]操作?参数1=值1&参数2=值2... //2.1 路由到默认或者绑定模块 Route::rule('blog/:id','index/read'); //2.2 路由到index模块 Route::rule('blog/:id','test/index/read'); //2.3、路由到动态的模块、控制器或者操作 //http://www.admindemo2.com/moviemodel/index/1 访问到的是test/Index/movieModel() Route::rule(':action/index/:id','test/Index/:action'); //http://www.admindemo2.com/moviemodel/lichihua/1 访问到的是test/Index/movieModel() Route::rule(':action/lichihua/:id','test/Index/:action'); //4 路由到操作方法 @[模块/控制器/]操作 //'blog/:id'=>'@index/blog/read', 系统会直接执行 Loader::action('index/blog/read'); //这种方式看起来似乎和第一种是一样的,本质的区别是直接执行某个控制器类的方法,而不需要去解析 模块/控制器/操作这些,同时也不会去初始化模块,视图的默认模板规则失效,所以这种情况下面,如果使用了视图模板渲染,则必须传入明确的参数 Route::get('test/:id','@test/Index/dongTest?status=1'); //?? //路由到类的方法 路由地址的格式为(动态方法):\类的命名空间\类名@方法名 或者(静态方法):\类的命名空间\类名::方法名 //可以支持执行任何类的方法,而不仅仅是执行控制器的操作方法 Route::rule('blog/:id','\app\index\service\Blog@read');//执行的是 \app\index\service\Blog类的read方法 Route::rule('blog/:id','\app\index\service\Blog::read'); //V5.0.4+版本开始,支持传入额外的参数作为方法的参数调用(用于参数绑定),例如: Route::rule('blog/:id','\app\index\service\Blog::read?status=1'); //路由到重定向地址 以/或者http 开头 Route::rule('wolichihua/:id','/test/:id'); //http://www.admindemo2.com/wolichihua/1 访问到了est/Index/dongTest即上面定义的test/:id' //资源路由 //在指向index模块的blog控制器新建index()、create($id)、save、read($id)、eidit($id)、update($id)、delete($id)方法然后动态注册(资源路由会自动注册7个路由规则分别对应这几个方法) 详情参考资源路由 Route::resource('blog','index/blog'); //或者路由配置 return [ // 定义资源路由 '__rest__'=>[ // 指向index模块的blog控制器 'blog'=>'index/blog', ], // 定义普通路由 'hello/:id'=>'index/hello', ]; //快捷路由 Route::controller('user','模块/控制器'); // 给User控制器设置快捷路由 控制器方法为 请求类型+方法名 如getInfo()与postInfo() // get http://localhost/user/phone post http://localhost/user/info Route::controller('user','index/User'); //路由别名 //我们希望使用user可以访问Home模块的User控制器的所有操作 那么我么定义别名为 Route::alias('user','home/User'); //或者 return [ '__alias__' => [ 'user' => 'home/User', ], ]; //路由别名可以指向任意一个有效的路由地址,例如下面指向一个类 // user 路由别名指向 User控制器类 Route::alias('user','\app\index\controller\User'); //路由分组 允许把相同前缀的路由定义合并分组 Route::group('blog',[ ':id' => ['Blog/read', ['method' => 'get'], ['id' => '\d+']], ':name' => ['Blog/read', ['method' => 'post']], ],['ext'=>'html']); //MISS路由:没有匹配到所有的路由规则后执行一条设定的路由,可以使用MISS路由功能, MISS路由配置后相当于开启了强制路由 //全局MISS路由 //Route::miss(); 放到路由的第一行才能生效,放到最后一行或者return里面不生效????? Route::miss('public/miss');//当没有匹配到所有的路由规则后,会路由到 public/miss路由地址。 //分组MISS路由 分组支持独立的MISS路由 // // //闭包支持: Route::get('hello/:name',function($name){ return 'Hello,'.$name; }); //闭包还支持模板师视图 Route::get('/', function () { return view('admin@home/index'); }); //路由绑定 // 绑定当前的URL到 index模块 Route::bind('index'); // 绑定当前的URL到 index模块的blog控制器 Route::bind('index/blog');//http://serverName/index/blog/read/id/5可以简化成http://serverName/read/id/5 ;如果定义了路由Route::get('index/blog/:id','index/blog/read');那么访问URL就变成了http://serverName/5 // 绑定当前的URL到 index模块的blog控制器的read操作 Route::bind('index/blog/read'); // 绑定命名空间 Route::bind('\app\index\controller','namespace');//通过http://serverName/blog/read/id/5就可以直接访问 \app\index\controller\Blog类的read方法。 // 绑定到类 Route::bind('\app\index\controller\Blog','class');//通过http://serverName/read/id/5就可以直接访问 \app\index\controller\Blog类的read方法。 //入口文件绑定 // 复制一份入口文件添加define('BIND_MODULE','admin'); 命名为demo.php 我们访问这个demo.php就访问的是admin模块 // 自动入口绑定 // 配置文件开启入口文件自动绑定模块 'auto_bind_module' => true, //复制一份index.php 改名为demo.php 访问index.php是访问index模块 访问的demo.php则访问得是demo模块 //域名路由 省略 ~~~ 定义路由后参数的获取问题: ~~~ Route::get('hello/:id','index/test/hello'); 以下三种是获取不到值的: dump(request()->get()); dump(request()->get('id')); dump(input('get.id')); 我们只有通过:下面这几个才能获取到 dump(request()->param()); dump(request()->param('id')); dump(request()->route()); dump(request()->route('id')); 怎么才能让get获取到? 参数绑定和?后面的如: public function hello($id){ dump(request()->get()); dump(input('get.')); } 浏览器输入:域名/hello/10?name=123 array (size=2) 'name' => string '123' (length=3) 'id' => string '10' (length=2) ~~~ 路由之后这些方法的controller和action的的值与实际的不同了 ~~~ 11.// 调用Request对象的path方法 12.{$Request.path} 13.// 调用Request对象的module方法 14.{$Request.module} 15.// 调用Request对象的controller方法 16.{$Request.controller} 17.// 调用Request对象的action方法 18.{$Request.action} ~~~