Laravel 路由
基础路由
// 两种目的地址:闭包和控制器
Route::get('foo', function () {
return 'Hello World';
});
Route::get('/user', 'UserController@index');
// 带参数的源地址和目的地址
Route::get('posts/{post}', function ($postId) {
//
});
参数
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]+']);
# 全局约束
// RouteServiceProvider
public function boot()
{
Route::pattern('id', '[0-9]+');
parent::boot();
}
Route::get('user/{id}', function ($id) {
// id 各位都是整数才能执行这儿
});
参数绑定
隐式绑定
Route::get('api/users/{user}', function (App\User $user) {
// 源地址中的 {} 中的变量名(即: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', App\User::class);
}
Route::get('profile/{user}', function ($user) {
//
});
自定义解析逻辑
// 在 app/Providers/RouteServiceProvider.php 中
public function boot()
{
parent::boot();
Route::bind('user', function ($value) {
return App\User::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');
组合
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">
命名路由
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 () {
// 在 "App\Http\Controllers\Admin" 命名空间下的控制器
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 () {
//
});
});
Route::get('/user', function () {
//
})->middleware('auth:api');
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(Illuminate\Routing\Route)
$name = Route::currentRouteName(); // 返回 mytest
$action = Route::currentRouteAction(); // 控制器中返回:App\Http\Controllers\TestController@test 闭包中返回:null