Laravel 路由

基础路由

// 两种目的地址:闭包和控制器
//闭包路由,此处是源地址
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 才能访问到