路由所在文件:
最基本的 Laravel 路由只接收一个 URI 和一个闭包,并以此为基础提供一个非常简单优雅的路由定义方法:
Route::get('No1', function () { return 'Hello, Welcome to Laravel5.8新世界'; });访问:http://cp.laravel58.cn/No1
对大多数应用而言,都是从 routes/web.php 文件开始定义路由。定义在 routes/web.php 中的路由可以通过在浏览器地址栏输入相应的 URL 进行访问,例如,你可以通过 http://blog.test/user 访问下面的路由:
Route::get('/user', 'UsersController@index'); // 控制器 方法有时候还需要注册一个路由响应多种 HTTP 请求动作 —— 这可以通过 match 方法来实现。或者,可以使用 any 方法注册一个路由来响应所有 HTTP 请求动作:
Route::match(['get', 'post'], 'foo', function () { return 'This is a request from get or post'; }); Route::any('bar', function () { return 'This is a request from any HTTP verb'; });测试 GET 请求的时候直接在浏览器中输入请求地址即可,
测试 POST 请求可以通过客户端工具,比如 postman,此外如果上面的路由是定义在 routes/web.php 的话,会返回 419 状态码导致无法请求成功,
在测试 POST 请求之前,需要将对应路由取消 CSRF 保护检查,取消的方法是在 app/Http/Middleware/VerifyCsrfToken 中设置排除检查路由
设置:
结果:
如果你需要定义一个重定向到其他 URI 的路由,可以使用 Route::redirect 方法,该方法非常方便,以至于你不需要再定义额外的路由或控制器来执行简单的重定向逻辑:
Route::redirect('/one', '/two'); Route::get('/two', function () { return '重定向到two'; });必选参数
有时我们需要在路由中获取 URI 请求参数。例如,如果要从 URL 中获取用户ID,需要通过如下方式定义路由参数:
//单个参数路由 Route::get('three/{id}', function ($id) { return $id; });
可以根据需要在路由中定义多个路由参数:
//多个参数 Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) { return $postId . '-' . $commentId; });根据上面的示例,路由参数需要通过花括号 {} 进行包裹并且是拼音字母,这些参数在路由被执行时会被传递到路由的闭包。路由参数名称不能包含 - 字符,如果需要的话可以使用 _ 替代,比如如果某个路由参数定义成 {post-id} 则访问路由会报错,应该修改成 {post_id} 才行。路由参数被注入到路由回调/控制器取决于它们的顺序,与回调/控制器名称无关。
可选参数
有必选参数就有可选参数,这可以通过在参数名后加一个 ? 标记来实现,这种情况下需要给相应的变量指定默认值,当对应的路由参数为空时,使用默认值:
Route::get('user/{name?}', function ($name = null) { return $name; }); Route::get('user/{name?}', function ($name = 'John') { return $name; });这时如果定义的路由是下面这个的话,访问 http://blog.test/user 会返回 John。
正则约束
可以通过路由实例上的 where 方法来约束路由参数的格式。where 方法接收参数名和一个正则表达式来定义该参数如何被约束:
//正则验证 Route::get('user/{name}', function ($name) { // $name 必须是字母且不能为空 //http://cp.laravel58.cn/user/Abc return $name;//Abc })->where('name', '[A-Za-z]+'); Route::get('user/{id}', function ($id) { // $id 必须是数字 //http://cp.laravel58.cn/user/123 return $id;//123 })->where('id', '[0-9]+'); Route::get('user/{id}/{name}', function ($id, $name) { // 同时指定 id 和 name 的数据格式 echo $id; return $name;//132abc })->where(['id' => '[0-9]+', 'name' => '[a-z]+']);使用正则约束还有一个好处就是避免了 user/{id} 和 user/{name} 的混淆。(如果不符合验证就会报404错误)
全局约束
如果想要路由参数在全局范围内被给定正则表达式约束,可以使用 pattern 方法。需要在 RouteServiceProvider 类的 boot 方法中定义这种约束模式:
/** * 定义路由模型绑定,模式过滤器等 * * @param \Illuminate\Routing\Router $router * @return void * @translator http://laravelacademy.org */ public function boot() { Route::pattern('id', '[0-9]+'); parent::boot(); }一旦模式被定义,将会自动应用到所有包含该参数名的路由中:
Route::get('user/{id}', function ($id) { // 只有当 {id} 是数字时才会被调用 });除此之外,该模式还会被应用到诸如下面这些路由参数上:(只要有id)
Route::get('post/{id}', function ($id) { // 只有当 {id} 是数字时才会被调用 }); Route::get('product/{id}', function ($id) { // 只有当 {id} 是数字时才会被调用 });很显然这种方式让代码更简洁,也为我们实现同一参数统一约束带来了方便。
编码/
Laravel 路由组件支持除 / 之外的所有字符,如果要在占位符中使用 / 需要通过 where 条件正则表达式显式允许:
Route::get('search/{search}', function ($search) { return $search; })->where('search', '.*');注:只有最后一个路由参数片段中才支持编码正斜杠/。
命名路由
命名路由为生成 URL 或重定向提供了方便,实现起来也很简单,在路由定义之后使用 name 方法链的方式来定义该路由的名称:
Route::get('user/profile', function () { // 通过路由名称生成 URL return 'my url: ' . route('profile'); })->name('profile');还可以为控制器动作指定路由名称:
Route::get('user/profile', 'UserController@showProfile')->name('profile');这样我们就可以通过以下方式定义重定向:
Route::get('redirect', function() { // 通过路由名称进行重定向 return redirect()->route('profile'); });为命名路由生成 URL
正如上面代码所展示的,为给定路由分配名称之后,就可以通过辅助函数 route 为该命名路由生成 URL 或者通过 redirect 函数进行重定向:
// 生成URL $url = route('profile'); // 生成重定向 return redirect()->route('profile');如果命名路由定义了参数,可以将该参数作为第二个参数传递给 route 函数。给定的路由参数将会自动插入到 URL 中:
Route::get('user/{id}/profile', function ($id) { $url = route('profile', ['id' => 1]); return $url; })->name('profile');这样,当我们访问 http://cp.laravel58.cn/user/123/profile 页面输出内容也是 http://cp.laravel58.cn/user/123/profile。
检查当前路由
如果你想要判断当前请求是否被路由到给定命名路由,可以使用 Route 实例上的 named 方法,例如,你可以从路由中间件中检查当前路由名称:
/** * 处理输入请求 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if ($request->route()->named('profile')) { // } return $next($request); }