注册路由规则
route
目录下的任何路由定义文件都是有效的,默认的路由定义文件是route.php
,但你完全可以更改文件名,或者添加多个路由定义文件(你可以进行模块定义区分,但最终都会一起加载)。
Route::rule('路由表达式','路由地址','请求类型'); 参数三不指定的话默认为任何请求类型有效
// 注册路由到index模块的News控制器的read操作
Route::rule('new/:id','index/News/read');
http://serverName/new/5
http://serverName/index/news/read/id/5
Route::rule('new/:id','News/update','POST');
Route::rule('new/:id','News/read','GET|POST');
| 类型 | 描述 | 快捷方法 |
|---|---|---|
| GET | GET请求 | get |
| POST | POST请求 | post |
| PUT | PUT请求 | put |
| DELETE | DELETE请求 | delete |
| PATCH | PATCH请求 | patch |
| * | 任何请求类型 | any |
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'); // 所有请求都支持的路由规则
路由表达式
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'); // 全动态地址
每个参数中以:
开头的参数都表示动态变量,并且会自动绑定到操作方法的对应参数
Route::get('blog/:year/[:month]','Blog/archive'); 可选定义
完全匹配
Route::get('new/:cate$', 'News/category'); 只有一个参数
Route::get('new/:cate', 'News/category'); 可以多个参数
// 开启路由完全匹配
'route_complete_match' => true,
额外参数
Route::get('blog/:id','blog/read?status=1&app_id=5');
status
和app_id
参数都是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]);
// 注册路由到index模块的News控制器的read操作 (新启用)
Route::rule('new/:id','index/News/read')->name('new_read');
变量规则
系统默认的变量规则设置是\w+
,只会匹配字母、数字和下划线字符,并不会匹配特殊符号和中文
'default_route_pattern' => '[\w\-]+',
局部变量规则
// 定义GET请求路由规则 并设置name变量规则
Route::get('new/:name', 'News/read')
->pattern(['name' => '\w+']);
全局变量规则
// 设置name变量规则(采用正则定义)
Route::pattern('name', '\w+');
// 支持批量添加
Route::pattern([
'name' => '\w+',
'id' => '\d+',
]);
组合变量规则
Route::get('item-<name>-<id>', 'product/detail')
->pattern(['name' => '\w+', 'id' => '\d+']);
Route::get('item<name><id>', 'product/detail')
->pattern(['name' => '[a-zA-Z]+', 'id' => '\d+']);
Route::get('item@<name>-<id>', 'product/detail')
->pattern(['name' => '\w+', 'id' => '\d+']);
Route::get('item-<name><id?>', 'product/detail')
->pattern(['name' => '[a-zA-Z]+', 'id' => '\d+']);
Route::get('item/:name-:id', 'product/detail')
->pattern(['name' => '\w+', 'id' => '\d+']);
动态路由
// 定义动态路由
Route::get('hello/:name', 'index/:name/hello');
Route::get('item-<name>-<id>', 'product_:name/detail')
->pattern(['name' => '\w+', 'id' => '\d+']);
路由地址
| 定义方式 | 定义格式 |
|---|---|
| 方式1:路由到模块/控制器 | '[模块/控制器/操作]?额外参数1=值1&额外参数2=值2...' |
| 方式2:路由到重定向地址 | '外部地址'(默认301重定向) 或者 ['外部地址','重定向代码'] |
| 方式3:路由到控制器的方法 | '@[模块/控制器/]操作' |
| 方式4:路由到类的方法 | '\完整的命名空间类::静态方法' 或者 '\完整的命名空间类@动态方法' |
| 方式5:路由到闭包函数 | 闭包函数定义(支持参数传入) |
| 方式6:路由到Response对象 | Response对象定义及设置 |
| 方式7:路由到模板文件 | 使用view方法( V5.1.3+) |
路由到模块/控制器/操作
// 路由到默认或者绑定模块
Route::get('blog/:id','blog/read');
// 路由到index模块
Route::get('blog/:id','index/blog/read');
Route::get('blog/:id','index/group.blog/read'); 多级控制器
// action变量的值作为操作方法传入
Route::get(':action/blog/:id', 'index/blog/:action');
// 变量传入index模块的控制器和操作方法
Route::get(':c/:a', 'index/:c/:a');
路由到操作方法
Route::get('blog/:id','@index/blog/read');
路由到类的方法
Route::get('blog/:id','\app\index\service\Blog@read');
Route::get('blog/:id','\app\index\service\Blog::read');
路由到重定向地址
Route::get('blog/:id','/blog/read/id/:id');
Route::get('blog/:id','blog/read');
Route::get('avatar/:id','/member/avatar/id/:id_small');
Route::get('blog/:id','http://blog.thinkphp.cn/read/:id');
Route::get('blog/:id','http://blog.thinkphp.cn/read/:id')->status(302);
Route::redirect('blog/:id','http://blog.thinkphp.cn/read/:id',302);
路由到模板
Route::view('hello/:name','index@hello');
Route::view('hello/:name','index@hello',['city'=>'shanghai']);
闭包定义
Route::get('hello', function () {
return 'hello,world!';
});
Route::get('hello/:name', function ($name) {
return 'Hello,' . $name;
});
依赖注入
Route::rule('hello/:name', function (Request $request, $name) {
$method = $request->method();
return '[' . $method . '] Hello,' . $name;
});
指定响应对象
Route::get('hello/:name', function (Response $response, $name) {
return $response
->data('Hello,' . $name)
->code(200)
->contentType('text/plain');
});
Route::get('hello/:name', response()
->data('Hello,' . $name)
->code(200)
->contentType('text/plain'));
// 对于不存在的static目录下的资源文件设置404访问
Route::get('static', response()->code(404));
路由参数
| 参数 | 说明 | 方法名 |
|---|---|---|
| method | 请求类型检测,支持多个请求类型 | method |
| ext | URL后缀检测,支持匹配多个后缀 | ext |
| deny_ext | URL禁止后缀检测,支持匹配多个后缀 | denyExt |
| https | 检测是否https请求 | https |
| domain | 域名检测 | domain |
| before | 前置行为(检测) | before |
| after | 后置行为(执行) | after |
| merge_extra_vars | 合并额外参数 | mergeExtraVars |
| complete_match | 是否完整匹配路由 | completeMatch |
| model | 绑定模型 | model |
| cache | 请求缓存 | cache |
| param_depr | 路由参数分隔符 | depr |
| ajax | Ajax检测 | ajax |
| pjax | Pjax检测 | pjax |
| response | 绑定response_send行为 | response |
| validate | 绑定验证器类进行数据验证 | validate |
| header | 设置Response的header信息 | header |
| append | 追加额外的参数(5.1.5+) | append |
| middleware | 注册路由中间件(5.1.6+) | middleware |
| merge_rule_regex | 合并路由规则(V5.1.6+) | mergeRuleRegex |
| filter | 请求变量过滤(V5.1.16+) | filter |
ext
和deny_ext
参数允许设置为空,分别表示不允许任何后缀以及必须使用后缀访问。
Route::get('new/:id','News/read',['ext'=>'html','https'=>true]);
Route::get('new/:id', 'News/read')
->ext('html')
->https();
// 定义GET请求路由规则 并设置禁止URL后缀为png、jpg和gif的访问
Route::get('new/:id', 'News/read')
->denyExt('jpg|png|gif');
域名检测
// 完整域名检测 只在news.thinkphp.cn访问时路由有效
Route::get('new/:id', 'News/read')
->domain('news.thinkphp.cn');
// 子域名检测
Route::get('new/:id', 'News/read')
->domain('news');
HTTPS检测
// 必须使用HTTPS访问
Route::get('new/:id', 'News/read')
->https();
// 必须使用HTTP访问
Route::get('new/:id', 'News/read')
->https(false);
请求变量检测
// 检查type变量
Route::post('new/:id', 'News/save')
->filter('type', 1);
// 检查多个请求变量
Route::post('new/:id', 'News/save')
->filter([ 'type' => 1,'status'=> 1 ]);
前置行为检测
Route::get('user/:id', 'index/User/read')
->before(['\app\index\behavior\UserCheck']);
<?php
namespace app\index\behavior;
class UserCheck
{
public function run()
{
if ('user/0' == request()->url()) {
return false;
}
}
}
后置行为执行
Route::get('user/:id', 'User/read')
->after(['\app\index\behavior\ReadInfo']);
<?php
namespace app\index\behavior;
use app\index\model\User;
class ReadInfo
{
public function run()
{
$id = request()->route('id');
app()->user = User::get($id);
}
}
合并额外参数
Route::get('new/:name$', 'News/read')
->mergeExtraVars();
路由绑定模型
Route::get('hello/:id', 'index/index/hello')
->model('id', '\app\index\model\User');
Route::get('hello/:id', 'index/index/hello')
->model('\app\index\model\User');
Route::rule('hello/:id', 'index/index/hello')
->model('id', '\app\index\model\User', false);
Route::rule('hello/:name/:id', 'index/index/hello')
->model('id&name', '\app\index\model\User');
Route::rule('hello/:id', 'index/index/hello')
->model(function ($id) {
$model = new \app\index\model\User;
return $model->where('id', $id)->find();
});
缓存路由请求
Route::get('new/:name$', 'News/read')
->cache(3600);
设置Header信息
Route::get('new/:name$', 'News/read')
->header('Access-Control-Allow-Origin','*');
Route::get('new/:name$', 'News/read')
->header([
'Access-Control-Allow-Origin'=>'*',
'Access-Control-Allow-Methods' => 'GET, POST, PATCH, PUT, DELETE',
]);
响应输出设置
Route::get('hello/:id', 'index/index/hello')->response([
'\app\index\behavior\Json',
]);
namespace app\index\behavior;
class Json
{
public function run($response)
{
// 调用Response类的方法进行设置
$response->contentType('application/json');
}
}
Route::get('hello/:id', 'index/index/hello')->response(function($response){
$response->contentType('application/json');
});
Route::get('hello/:id', function () {
return json('hello,world!');
});
全局路由参数
Route::option('ext','html')->option('cache', 600);
动态参数
Route::get('new/:name$', 'News/read')
->option('rule','admin');
Route::get('new/:name$', 'News/read')
->rule('admin');
路由中间件
Route::rule('hello/:name','hello')
->middleware('Auth');
Route::group('hello', function(){
Route::rule('hello/:name','hello');
})->middleware('Auth');
Route::rule('hello/:name','hello')
->middleware('Auth:admin');
Route::rule('hello/:name','hello')
->middleware(Auth::class, 'admin');
Route::rule('hello/:name','hello')
->middleware([Auth::class, 'Check']);
Route::rule('hello/:name','hello')
->middleware([Auth::class, 'Check'], 'admin');
Route::rule('hello/:name','hello')
->middleware(['Auth:admin', 'Check:editor']);
路由缓存
'route_check_cache' => true,
'route_check_cache_key' => 'get_route_key',
function get_route_key($request)
{
return md5($request->url(true) . ':' . $request->method() . ':' . ($request->isAjax() ? 1 : 0));
}
跨域请求
Route::get('new/:id', 'News/read')
->ext('html')
->allowCrossDomain();
跨域请求一般会发送一条OPTIONS
的请求,一旦设置了跨域请求的话,不需要自己定义OPTIONS
请求的路由,系统会自动加上。
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods:GET, POST, PATCH, PUT, DELETE
Access-Control-Allow-Headers:Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With
Route::get('new/:id', 'News/read')
->ext('html')
->header('Access-Control-Allow-Origin','thinkphp.cn')
->header('Access-Control-Allow-Credentials', 'true')
->allowCrossDomain();
注解路由
// 使用注解路由
'route_annotation' => true,
只需要直接在控制器类的方法注释中定义(通常称之为注解路由)
/**
* @param string $name 数据名称
* @return mixed
* @route('hello/:name')
*/
public function hello($name)
{
return 'hello,'.$name;
}
/**
* @param string $name 数据名称
* @route('hello/:name','get')
* ->https()
* ->pattern(['name' => '\w+'])
*
* @return mixed
*/
public function hello($name)
{
return 'hello,'.$name;
}
路由分组
把相同前缀的路由定义合并分组,这样可以简化路由定义,并且提高路由匹配的效率
Route::group('分组名(字符串)或者分组路由参数(数组)','分组路由规则(数组或者闭包)');
Route::group('blog', [
':id' => 'Blog/read',
':name' => 'Blog/read',
])->ext('html')->pattern(['id' => '\d+']);
Route::group('blog', function () {
Route::rule(':id', 'blog/read');
Route::rule(':name', 'blog/read');
})->ext('html')->pattern(['id' => '\d+', 'name' => '\w+']);
Route::group(['method' => 'get', 'ext' => 'html'], function () {
Route::rule('blog/:id', 'blog/read');
Route::rule('blog/:name', 'blog/read');
})->pattern(['id' => '\d+', 'name' => '\w+']);
Route::group(['method' => 'get', 'ext' => 'html'], function () {
Route::group('blog', function () {
Route::rule('blog/:id', 'blog/read');
Route::rule('blog/:name', 'blog/read');
});
})->pattern(['id' => '\d+', 'name' => '\w+']);
Route::group('blog', function () {
Route::get(':id', 'blog/read');
Route::post(':id', 'blog/update');
Route::delete(':id', 'blog/delete');
})->ext('html')->pattern(['id' => '\d+']); 简化为下面的
Route::group('blog', function () {
Route::get(':id', 'read');
Route::post(':id', 'update');
Route::delete(':id', 'delete');
})->prefix('blog/')->ext('html')->pattern(['id' => '\d+']);
延迟路由解析
// 开启路由延迟解析
'url_lazy_route' => true,
传入额外参数
Route::group('blog', [
':id' => 'Blog/read',
':name' => 'Blog/read',
])->ext('html')
->pattern(['id' => '\d+'])
->append(['group_id'=>1]);
全局MISS路由
没有匹配到所有的路由规则后执行一条设定的路由,可以注册一个单独的MISS
路由 一旦设置了MISS路由,相当于开启了强制路由模式
Route::miss('public/miss');
分组MISS路由
Route::group('blog', function () {
Route::rule(':id', 'blog/read');
Route::rule(':name', 'blog/read');
Route::miss('blog/miss');
})->ext('html')
->pattern(['id' => '\d+', 'name' => '\w+']);
资源路由
Route::resource('blog','index/blog');
注册了一个名称为blog
的资源路由到index
模块的Blog
控制器,系统会自动注册7个路由规则
| 标识 | 请求类型 | 生成路由规则 | 对应操作方法(默认) |
|---|---|---|---|
| index | GET | blog | index |
| create | GET | blog/create | create |
| save | POST | blog | save |
| read | GET | blog/:id | read |
| edit | GET | blog/:id/edit | edit |
| update | PUT | blog/:id | update |
| delete | DELETE | blog/:id | delete |
Route::resource('blog', 'index/blog')
->vars(['blog' => 'blog_id']); 改变默认的id参数名
public function edit($blog_id)
{
}
// 只允许index read edit update 四个操作
Route::resource('blog', 'index/blog')
->only(['index', 'read', 'edit', 'update']);
// 排除index和delete操作
Route::resource('blog', 'index/blog')
->except(['index', 'delete']);
Route::rest('create',['GET', '/add','add']);
Route::rest([
'save' => ['POST', '', 'store'],
'update' => ['PUT', '/:id', 'save'],
'delete' => ['DELETE', '/:id', 'destory'],
]);
资源嵌套
Route::resource('blog.comment','index/comment');
blog/:blog_id/comment/:id
blog/:blog_id/comment/:id/edit
// 更改嵌套资源路由的blog资源的资源变量名为blogId
Route::resource('blog.comment', 'index/comment')
->vars(['blog' => 'blogId']);
快捷路由
// 给User控制器设置快捷路由
Route::controller('user','index/User');
路由别名
// user 别名路由到 index/User 控制器
Route::alias('user','index/User');
// user 路由别名指向 User控制器类
Route::alias('user','\app\index\controller\User');
// user 别名路由到 index/user 控制器
Route::alias('user', 'index/user', ['ext' => 'html']);
操作方法黑白名单
// user 别名路由到 index/user 控制器
Route::alias('user', 'index/user', [
'ext' => 'html',
'allow' => 'index,read,edit,delete',
]);
// user 别名路由到 index/user 控制器
Route::alias('user', 'index/user', [
'ext' => 'html',
'except' => 'save,delete',
]);
// user 别名路由到 index/user 控制器
Route::alias('user', 'index/user', [
'ext' => 'html',
'allow' => 'index,save,delete',
'method' => ['index' => 'GET', 'save' => 'POST', 'delete' => 'DELETE'],
]);
绑定到模块/控制器/操作
// 绑定当前的URL到 index模块
Route::bind('index');
// 绑定当前的URL到 index模块的blog控制器
Route::bind('index/blog');
// 绑定当前的URL到 index模块的blog控制器的read操作
Route::bind('index/blog/read');
Route::get('index/blog/:id','index/blog/read');
绑定到命名空间
// 绑定命名空间
Route::bind(':\app\index\controller');
绑定到类
// 绑定到类
Route::bind('\app\index\controller\Blog');
入口文件绑定
// 绑定到index模块 执行应用并响应
Container::get('app')->bind('index')->run()->send();
Container::get('app')->bind('index/index')->run()->send();
// 开启入口文件自动绑定模块
'auto_bind_module' => true,
域名路由
Route::domain('blog', function () {
// 动态注册域名的路由规则
Route::rule('new/:id', 'index/news/read');
Route::rule(':user', 'index/user/info');
});
Route::domain('blog', [
// 动态注册域名的路由规则
':id' => ['blog/read', ['method' => 'GET'], ['id' => '\d+']],
':name' => 'blog/read',
]);
Route::domain(['blog', 'admin'], function () {
// 动态注册域名的路由规则
Route::rule('new/:id', 'index/news/read');
Route::rule(':user', 'index/user/info');
});
Route::group('', function () {
// 动态注册域名的路由规则
Route::rule('new/:id', 'index/news/read');
Route::rule(':user', 'index/user/info');
})->crossDomainRule();
域名绑定
// blog子域名绑定到blog模块
Route::domain('blog', 'blog');
// 完整域名绑定到admin模块
Route::domain('admin.thinkphp.cn', 'admin');
// IP绑定到admin模块
Route::domain('114.23.4.5', 'admin');
// 原来的URL访问
http://www.thinkphp.cn/blog/article/read/id/5
// 绑定到blog子域名访问
http://blog.thinkphp.cn/article/read/id/5
// blog子域名绑定到index模块的blog控制器
Route::domain('blog', 'index/blog');
// 原来的URL访问
http://www.thinkphp.cn/index/blog/read/id/5
// 绑定到blog子域名访问
http://blog.thinkphp.cn/read/id/5
'url_domain_root' => 'thinkphp.com.cn'
Route::domain('blog', function () {
// 动态注册域名的路由规则
Route::rule('new/:id', 'index/news/read');
Route::rule(':user', 'index/user/info');
})->bind('blog');
// blog子域名绑定命名空间
Route::domain('blog', ':\app\blog\controller');
// blog子域名绑定到类
Route::domain('blog', '\app\blog\controller\Article');
泛域名部署
// 绑定泛二级域名域名到book模块
Route::domain('*', 'book');
// 绑定泛三级域名到user模块
Route::domain('*.user', 'user');
通过Request::panDomain()
获取当前的泛域名值
通过Request::param('name')
获取当前泛域名的值
绑定到Response对象
// 绑定域名到Response对象
Route::domain('test', response()->code(404));
Route::domain('blog', function () {
// 动态注册域名的路由规则
Route::rule('new/:id', 'index/news/read');
})->bind('blog');
传入额外参数
Route::domain('blog', function () {
// 动态注册域名的路由规则
Route::rule('new/:id', 'index/news/read');
Route::rule(':user', 'index/user/info');
})->append(['app_id'=>1]);
Route::domain('blog', 'blog')
->append(['app_id'=>1]);
URL生成使用 \think\facade\Url::build()
方法或者使用系统提供的助手函数url()
,参数一致:
Url::build('地址表达式',['参数'],['URL后缀'],['域名'])
url('地址表达式',['参数'],['URL后缀'],['域名'])
Route::rule('blog/:id','index/blog/read');
Url::build('index/blog/read', 'id=5&name=thinkphp');
Url::build('index/blog/read', ['id' => 5, 'name' => 'thinkphp']);
url('index/blog/read', 'id=5&name=thinkphp');
url('index/blog/read', ['id' => 5, 'name' => 'thinkphp']);
使用模块/控制器/操作生成
// 生成index模块 blog控制器的read操作 URL访问地址
Url::build('index/blog/read', 'id=5&name=thinkphp');
// 使用助手函数
url('index/blog/read', 'id=5&name=thinkphp');
/index.php/blog/5/name/thinkphp.html
使用控制器的方法生成
// 这里采用配置方式定义路由 动态注册的方式一样有效
Route::get('blog/:id', '@index/blog/read');
// 生成index模块 blog控制器的read操作 URL访问地址
Url::build('@index/blog/read', 'id=5');
// 使用助手函数
url('@index/blog/read', 'id=5');
/index.php/blog/5.html
使用类的方法生成
// 这里采用配置方式定义路由 动态注册的方式一样有效
Route::rule(['blog','blog/:id'],'\app\index\controller\blog@read');
// 生成index模块 blog控制器的read操作 URL访问地址
Url::build('blog?id=5');
url('blog?id=5');
/index.php/blog/5.html
直接使用路由地址
Route::get('blog/:id' , 'index/blog/read');
Url::build('/blog/5');
/index.php/blog/5.html
URL后缀
Url::build('index/blog/read', 'id=5', 'shtml');
url('index/blog/read', 'id=5', 'shtml');
域名生成
Url::build('index/blog/read', 'id=5', 'shtml', true);
url('index/blog/read', 'id=5', 'shtml', true);
Route::domain('blog','index/blog');
http://blog.thinkphp.cn/read/id/5.shtml
Url::build('index/blog/read','id=5','shtml','blog');
url('index/blog/read','id=5','shtml','blog'); 指定域名
Url::build('index/blog/read','id=5','shtml','blog.thinkphp.cn');
url('index/blog/read','id=5','shtml','blog.thinkphp.cn');
http://blog.thinkphp.cn/read/id/5.shtml
Url::build('index/blog/read@blog', 'id=5');
url('index/blog/read@blog', 'id=5');
url('index/blog/read@blog.thinkphp.cn', 'id=5');
生成锚点
Url::build('index/blog/read#anchor@blog','id=5');
url('index/blog/read#anchor@blog','id=5');
http://blog.thinkphp.cn/read/id/5.html#anchor
锚点和域名一起使用的时候,注意锚点在前面,域名在后面
隐藏或者加上入口文件
Url::root('/index.php');
Url::build('index/blog/read','id=5');
隐藏index.php
:
Url::root('/');
Url::build('index/blog/read','id=5');
root
方法只需要调用一次即可
文章转载自php自学笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




