URL请求的执行流程
用户请求 -> 路由解析 -> 调度请求 -> 执行操作 -> 响应输出
路由就像一个总调度,把用户不同的请求,分发到对应的URL地址上
1.路由作用
* 根据事先定义的路由规则,检验URL请求,确定执行或拒绝
* 路由规则可自定义,隐藏了原URL地址,使访问更安全,地址更优雅。
eg:http://tp5.com/edu/test/demo 和 htpp://tp5.com/demo
2.路由规则写在哪里
* 路由规则写在与应用配置统计的route.php文件中
* 路由规则主要使用路由类Route::rule()方法注册
eg:think\Route::rule('demo','edu/test/demo'); //route.php命名空间是全局的,think前不需要加\
路由模式
1.普通模式
* 配置:'url_route_on'=>false
* 访问:全部采用PATH_INFO格式
2.混合模式
* 配置:'url_route_on'=>'true','url_route_must'=>false
* 已注册用路由访问,未注册仍用PATH_INFO访问 默认
3.强制模式
* 配置:'url_route_on'=>true,'url_route_must'=>true,
* 全部必须采用路由模式,包括首页'/'
路由注册
1.动态方法
Route::rule('路由规则','路由地址','请求类型',[路由参数],[变量规则]);
注意:此方式请求类型必须大写
2.配置数组(配置文件方式):
return[
'路由规则'=>'路由地址',
'路由规则'=>['路由地址',[路由参数],[变量规则]]
];
eg:think\Route::rule('demo/:lession','index/index/demo','GET',['ext'=>'shtml'],['lession'=>'\w{1,10}']);
return[
'demo/:lession'=>['index/index/demo',['method'=>'get','ext'=>'shtml'],['lession'=>'\w{1,10}']],
];
路由规则
1.路由规则就是用户最总用来访问的URL地址,并非原始URL地址
2.路由规则的组成部分(静态路由和动态路由)
路由标识符 / :变量名1 /:变量名2 / [:可选变量名]
eg:think\Route::rule('demo/:name/:lession','index/index/demo','GET',['ext'=>'shtml'],['name'=>'\w{2,5}','lession'=>'\w{1,10}']);
路由地址
1.路由地址就是用户用路由规则访问页面时,真实跳转到的地址
2.路由地址的种类
* 路由到:模块/控制器/操作
* 路由到:操作方法
* 路由到:类的方法(动态与静态)
* 路由到:重定向地址(301)
* 路由到:闭包函数
3.路由到:模块/控制器/操作
* 语法:Route::rule('路由规则','模块/控制器/操作');
* 重点理解
-> 可访问控制器:'url_controller_layer'=>'controller',(默认访问控制层)
-> 按从右到左的顺序进行地址解析:操作->控制器->模块
-> 支持额外参数(查询方式):?变量名1=值1&变量名2=值2 ....
eg:think\Route::get('demo/:name','index/index/demo?lession='php');
4.路由到:操作方法
* 语法:Route::rule('路由规则','@模块/控制器/操作');
* 重点理解
->跳过模块初始化,直接执行控制器中的方法
->模块初始化:配置文件和公共文件
->调用视图时必须设置完整模板文件的路径
eg:think\Route::get('demo/:name','@index/index/demo?lession='php');
5.路由到:类的方法
* 语法:Route::rule('路由规则','\完整命名空间\类名@动态操作');
* 语法:Route::rule('路由规则','\完整命名空间\类名::静态操作');
* 重点理解:
->类必须创建在应用目录或子目录中
->静态方法支持外部动态,但建议在语法上分开
->为了项目规范,除非不得已,否则尽可能少用
eg:think\Route::get('test','\app\Test@test');
6.路由到:闭包函数
* 语法:
Route::rule('路由规则',function([参数]){
//闭包函数代码
});
* 重点理解
->闭包就是函数中的函数,或方法中的方法
->闭包函数可以接受通过路由规则传过来的参数
->不再执行任何操作,相当于把方法直接定义参数中
eg:think\Route::get('myfunc/:lession',function($lession){
return '我是闭包函数内容'.$lession;
});
7.路由到:重定向地址(301)
* 语法:Route::rule('路由规则','重定向地址');
* 重点理解
->重定向地址:'/'或者'http://'开头的外部地址
->'/':第以当前可访问的web目录开始: 如'public'
->外部地址是301跳转,适用于网站迁移
eg:think\Route::rule('myjump','/demo.php'); //public文件夹下新建demo.php文件
eg:think\Route::rule('myjump','http://www.baidu.com');
路由参数
1.路由参数是用来验证当前的路由规则是否有效的重要依据
2.路由参数的种类
* 请求类型:['method'=>'get|post']
* URL后缀:['ext'=>'html|shtml'] / ['deny_ext'=>'php']
* 回调函数:['callback'=>'回到函数名称']
* 域名检测:['domain'=>'tp5.com']
* 更多参数,如绑定模块/合并额外参数等请查阅手册
3.请求类型
* 最常用的是:GET和POST,其他了解即可(如delete,put等)
* 使用方法
->如注册方法已声明类型则无需设置:Route::get()/post();
->Route::rule()/any():['method'=>'get|post'];
->使用路由配置文件数组定义:['method'=>'get|post']
eg:think\Route::rule('demo','index/index/demo','GET',[],[]);
eg:think\Route::get('demo','index/index/demo',[],[]);
eg:return[
'demo'=>['index/index/demo',['method'=>'get'],[]],
];
4.URL后缀/扩展名
* 限定可访问路由规则的URL后缀名称,默认为html
* 使用方法
->允许的URL后缀:['ext'=>'html|shtml']
->禁止的URL后缀:['deny_ext'=>'jpg|png']
->允许URL后缀为空:['ext'=>'']
->禁止的URL后缀为空:['deny_ext'=>'']
5.用回调来验证路由规则
* 回调函数返回true则路由规则有效,否则无效
* 使用方法
->回调函数写在应用公共方法中:common.php
->语法:['callback'=>'回调函数名称']
eg:用回调来检测是否存在某个应用配置项,来决定是否执行路由规则
eg:return [
'demo'=>['index/index/demo',['method'=>'get','callback'=>'my_check'],[]],
];
common.php
function my_check()
{
$domain = \think\Config::get('site_domain');
if($domain){
return true;
}else{
return false;
}
}
6.域名验证
* 检测调用当前路由规则的域名是不是参数所指定的域名
* 使用方法
->语法格式:['domain'=>'域名']
->支持子域名:['domain'=>'子域名']
eg:return [
'demo'=>['index/index/demo',['method'=>'get','domain'=>'tp5.com'],[]],
];
变量规则
1.正则表达式
* 描述字符串匹配模式,主要用于字符串的查找/替换与分割
2.正则表达式组成部分
* 由定界符、原子、元字符和修正符四部分组成
* 定界符:通常用#,~~,/等非原子或元字符反斜杠\都行
* 原子:需要匹配的字符,由可见与不可见字符组成
* 元字符:限定或修饰原子部分,不能单独使用
* 修正符:限定或修饰整个正则表达式
3.路由变量规则
* 路由变量规则用来对动态路由规则中的变量部分,进行校验的依据
* 变量规则的使用域
->局部变量规则:仅对当前路由有效
->全局变量规则:已注册的全部路由规则都要遵守
* Route::rule('路由规则','路由地址','请求类型',[路由参数],['变量规则']);
* 变量规则:['变量名1'=>'正则表达式1','变量名2'=>'正则表达式2']
eg:Route::rule('demo','index/demo','GET',[],['id'=>'\d{4}']);
* convention.php 中 'url_param_type'等于0的时候是按键值对解析 等于1按顺序解析
eg:think\Route::get('test/:name/:age','index/index/test',[],[
'name'=>'[a-zA-Z]+', //name必须是纯字符,至少有一个字符
'age'=>'\d{2}', //年龄字段必须是一个整数,而且必须是2为
]);
4.全局变量规则
* 单独创建:Route::pattern('变量名','正则表达式');
* 批量创建:
Route::pattern([
'变量名1'=>'正则表达式1',
'变量名2'=>'正则表达式2',
]);
eg:think\Route::pattern([
'name'=>'[a-zA-Z]+', //name必须是纯字符,至少有一个字符
'age'=>'\d{2}', //年龄字段必须是一个整数,而且必须是2为
]);
think\Route::get('test/:name/:age','index/index/test'); //这个就不需要设置变量规则了
* 还可以这么用
return [
'__pattern__'=>[
'name'=>'[a-zA-Z]+', //name必须是纯字符,至少有一个字符
age'=>'\d{2}', //年龄字段必须是一个整数,而且必须是2为
],
'test/:name/:age'=>'index/index/test',
];
* 当全局与局部的变量规则作用在同一个路由变量上面时,局部规则覆盖全局规则,及局部的优先级高于全局
路由分组
1.什么情况下,适合进行路由分组
* 当多个路由规则中,有相同的路由前缀时,分组可提高效率。
2.分组方法
* 动态方法:Route::group('分组名称',[路由地址,[路由参数],[变量规则]])
* 配置数组:return ['规则'=>[路由地址,[路由参数],[变量规则]]]
* 根据路由参数分类
->闭包分组:
Route::group('',function(){
//创建路由规则语句;
})
->虚拟分组:根据相同路由参数进行分组
eg:
return [
'[demo]'=>[
':id'=>['index/user/demo1',['method'=>'get'],['id'=>'\d{2,4}']],
':name'=>['index/user/demo2',['method'=>'get'],['name'=>'[a-zA-Z]+']],
':isOk'=>['index/user/demo3',['method'=>'get'],['isOk'=>0|1]],
],
];
think::Route::group('demo',[
':id'=>['index/user/demo1',['method'=>'get'],['id'=>'\d{2,4}']],
':name'=>['index/user/demo2',['method'=>'get'],['name'=>'[a-zA-Z]+']],
':isOk'=>['index/user/demo3',['method'=>'get'],['isOk'=>0|1]],
]);
//闭包函数实现
think::Route::group('demo',function(){
think\Route::get(':id','index/user/demo1',[],['id'=>'\d{2,4}']);
think\Route::get(':name','index/user/demo2',[],['name'=>'[a-zA-Z]+']);
think\Route::get(':isOk','index/user/demo3',[],['isOk'=>0|1]);
});
* 虚拟分组
think::Route::group(['name'=>'demo','method'=>'get'],[
':id'=>['index/user/demo1',[],['id'=>'\d{2,4}']],
':name'=>['index/user/demo2',[],['name'=>'[a-zA-Z]+']],
':isOk'=>['index/user/demo3',[],['isOk'=>0|1]],
]);
//还可以简化
think::Route::group(['name'=>'demo','method'=>'get','prefix'=>'index/user/'],[
':id'=>['demo1',[],['id'=>'\d{2,4}']],
':name'=>['demo2',[],['name'=>'[a-zA-Z]+']],
':isOk'=>['demo3',[],['isOk'=>0|1]],
]);
//再次简化
think::Route::group('demo',[ //分组名称
':id'=>'demo1', //路由规则
':name'=>'demo2',
':isOk'=>'demo3',
],[ //路由参数
'method'=>'get',
'prefix'=>'index/user/'
],[ //变量规则
'id'=>'\d{2,4}',
'name'=>'[a-zA-Z]+',
'isOk'=>0|1
]);
别名路由
1.快速注册同一控制器下所有操作方法(不支持变量规则)
*动态方法:Route::alias('规则名称','模块/控制器',[路由参数]);
*静态数组:
return[
'__alias'=>['规则名称','模块/控制器',[路由参数]]
];
eg:think\Route::alias('math','index/demo',[
'ext'=>'html',
'allow'=>'add,sub', //白名单:允许访问的方法
'except'=>'mult,del' //黑名单:不允许访问的方法
]);
//默认从public下开始查找,当application下也有Test.php时就找不到控制器中的了
think\Route::alias('php','\app\index\controller\Test');
return [
'__alias'=>[
'math'=>[
'index/demo',
['ext'=>'html','except'=>'add,sub'],
],
],
];
* 别名路由,可以进一步简化路由规则,但是不支持变量规则,借助路由参数的allow和except参数实现黑白名单功能
路由绑定
1.入口绑定
* 说明:在入口文件中添加:BIND_MODULE系统常量
//将当前访问绑定模块/控制器 注:绑定后访问时可省略模块/控制器
define('BIND_MODULE','index'); //模块级
define('BIND_MODULE','index/demo'); //控制器级
2.入口自动绑定
* 入口自动绑定模块设置:'auto_bind_module'=>true,
* 创建需要绑定的入口文件,例如:在public目录下创建admin.php
* 创建与入口文件对应的模块与控制器:application/admin/controller/Index.php,并创建默认index()方法
* 直接访问:域名/admin.php,就会自动执行admin模块中默认控制器中的默认方法
3.动态绑定
* 语法:Route::bind('模块[/控制器][/操作]')
* 绑定当前的URL到模块 Route::bind('模块');
* 绑定当前的URL到模块下面的控制器 Route::bind('模块/控制器');
* 绑定当前的URL到模块下面的控制器中的指定操作 Route::bind('模块/控制器/操作');
4.绑定到命名空间或者类
* 绑定当前的URL到指定命名空间 注:可以直接访问Index模块中的控制器和方法
-> Route::bind('app\index\controller','namespace');
-> 此前,所有采用该命名空间的类都可以直接访问
* 绑定当前的URL到类 注:可以直接访问Demo类中的方法
-> Route::bind('app\index\controller\Demo','class');
-> 此前,所有Demo类中的方法,可以直接访问
-> 特别注意:这种绑定形式会直接跳过模块配置文件和公共文件
网友评论