基础路由
// 两种目的地址:闭包和控制器 //闭包路由,此处是源地址 Route::get('foo', function () { return 'Hello World'; }); //控制器路由 Route::get('/user', 'UserController@index'); // 带参数的源地址和目的地址 Route::get('posts/{post}', function ($postId) { // }); //例如 Route::get('posts/{nameunction ($name) { // });
带参数路由
Route::get('posts/{post}/comments/{comment}', function ($pid, $cid) { //带多个参数 }); Route::get('user/{name?}', function ($name = 'John') { // 一定要给可选参数设置默认值 return $name; //可选参数 }); # 对参数局部约束 Route::get('user/{id}', function ($id) { //单个参数约束 })->where('id', '[0-9]+'); Route::get('user/{id}/{name}', function ($id, $name) { //多个参数约束 })->where(['id' => '[0-9]+', 'name' => '[a-z]+']); # 全局约束 //在apphttpproviders目录下的 RouteServiceProvider文化 public function boot() { //设置的参数约束 Route::pattern('id', '[0-9]+'); parent::boot(); } Route::get('user/{id}', function ($id) { // id 各位都是整数才能执行这儿 });
参数绑定
隐式绑定
Route::get('api/users/{user}', function (AppUser $user) { //源地址,function目的地址,如果访问'api/users/1,会取出user值为1的数据,并返回1的email // 源地址中的 {} 中的变量名(即:user)和传参名必须完全一致 return $user->email; }); # 自定义键名,在模型中修改(默认指的是数据库中的主键 id): # App/User.php public function getRouteKeyName() { return 'slug'; // api/users/2 // select * from `users` where `slug` = 2 limit 1 }
显式绑定
# RouteServiceProvider public function boot() { parent::boot(); //这里写了路由那就不用写了 Route::model('user', AppUser::class); } Route::get('profile/{user}', function ($user) { // });
自定义解析逻辑
// 在 app/Providers/RouteServiceProvider.php 中 public function boot() { parent::boot(); Route::bind('user', function ($value) { return AppUser::where('name', $value)->first() ?? abort(404); }); }
// 在 app/User.php 中 public function resolveRouteBinding($value) { return $this->where('name', $value)->first() ?? abort(404); }
http 请求方法
单个方法
Route::get($uri, $callback); Route::post($uri, $callback); Route::put($uri, $callback); // 全体更新 Route::patch($uri, $callback); // 局部更新 Route::delete($uri, $callback); Route::options($uri, $callback); // 允许客户端检查性能 Route::resource('photos', 'PhotoController'); resource会生成一下七条记录
方法 | uri | 路由名称 | 控制器@方法 |
---|---|---|---|
GET | photos | photos.index | PhotoController@index |
POST | photos | photos.store | PhotoController@store |
GET | photos/create | photos.create | PhotoController@create |
GET | photos/{photo} | photos.show | PhotoController@show |
PUT/PATCH | photos/{photo} | photos.update | PhotoController@update |
DELETE | photos/{photo} | photos.destroy | PhotoController@destroy |
GET | photos/{photo}/edit | photos.edit | PhotoController@edit |
* GET /photos index() // 展示照片列表 * POST /photos store() // 添加照片 * GET /photos/create create() // 展示用来创建照片的表单 * GET /photos/{id} show($id) // 展示一张照片 * PUT /photos/{id} update($id) // 更新一张照片 * DELETE /photos/{id} destroy($id) // 移除一张照片 * GET /photos/{id}/edit edit($id) // 展示编辑照片表单
组合
Route::any($uri, $callback); // 任意 method Route::match(['get', 'post'], '/', function () { // });
注意点
在 web.php 路由里的 POST, PUT, DELETE 方法,在提交表单时候必须加上CSRF参数。
<form method="POST" action="/profile">
@csrf
...
</form>
表单伪造
<input type="hidden" name="_method" value="PUT"> // 或者 @method('PUT')
命名路由
Route::get('user/profile', function () { // })->name('profile'); // 使用 $url = route('profile'); return redirect()->route('profile'); // 带参数的情况 Route::get('user/{id}/profile', function ($id) { // })->name('profile'); $url = route('profile', ['id' => 1]);
根据需求丰富路由
命名空间
Route::namespace('Admin')->group(function () { // 在 "AppHttpControllersAdmin" 命名空间下的控制器 Route::get('/user', 'UserController@index'); // Admin/UserController@index Route::get('/user2', 'UserController@user2'); // Admin/UserController@user2 }); //但是不推荐使用这种方法,因为使用的闭包,会造成后期优化路由的时候造成困难 Route::namespace('Admin')->get('/user', 'UserController@index'); // Admin/UserController@index Route::namespace('Admin')->get('/user2', 'UserController@user2'); // Admin/UserController@user2
子域名路由
Route::domain('{account}.myapp.com')->group(function () { Route::get('user/{id}', function ($account, $id) { // }); }); # 在注册根域路由之前注册子域路由。 这将防止根域路由覆盖具有相同 URI 路径的子域路由。
路由前缀
Route::prefix('admin')->group(function () { Route::get('users', function () { }); }); // 相当于 Route::get('admin/users', function () { });
路由命名前缀
Route::name('admin.')->group(function () { Route::get('users', function () { })->name('users'); // name('admin.users') });
添加中间件
//中间件相当于在路由到控制器之间加了一层限制
Route::middleware('throttle:60,1')->group(function () { Route::get('/user', function () { //限制只能访问user控制器60次 }); }); Route::get('/user', function () { //认证 })->middleware('auth'); Route::middleware(['first', 'second'])->group(function () { Route::get('/', function () { // 使用 `first` 和 `second` 中间件 }); Route::get('user/profile', function () { // 使用 `first` 和 `second` 中间件 }); });
一些简化的基本路由
# 重定向路由 Route::redirect('/here', '/there'); Route::permanentRedirect('/here', '/there'); // 301 Route::redirect('/here', '/there', 301); // 第三个参数不写则默认为 302 # 只需要返回一个视图 Route::view('/welcome', 'welcome'); Route::view('/welcome', 'welcome', ['name' => 'Taylor']);
默认路由
Route::fallback(function () { // 处理 404 }); // 一定要放在所有路由最后面
获取当前路由信息
// 假设有路由: Route::get('/', 'TestController@test')->name("mytest"); $route = Route::current(); // 返回 object(IlluminateRoutingRoute) $name = Route::currentRouteName(); // 返回 mytest $action = Route::currentRouteAction(); // 控制器中返回:AppHttpControllersTe
api路由
api路由与web路由并没有什么差别,只是在访问api路由的时候,需要添加api
例如:www.sean.com/test 使用api路由后 www.sean.com/api/test 才能访问到