關於Laravel的二、三事(1)簡單的路由

AlanJager發表於2020-04-07

用於記錄學習Laravel的筆記,今天學習的是關於路由的簡單知識

基本路由

最簡單的路由,由接收一個url和一個閉包的形式展示:

Route::get('/', function () {
    return 'Hello World';
});

Route::post('foo/bar', function () {
    return 'Hello World';
});

Route::put('foo/bar', function () {
    //
});

Route::delete('foo/bar', function () {
    //
});
對同一個路由,我們可以設定使其接受多個動詞:

Route::match(['get', 'post'], '/', function () {
    return 'Hello World';
});

其中如果使用了any設定,那麼所有動詞均能被接受:

Route::any('foo', function () {
    return 'Hello World';
});


路由引數

當你的路由需要傳入引數的時候,Laravel提供了傳入引數的路由方式,當只有一個引數時:

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

當傳入多個引數時:

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

如果引數不是必須的,那麼可以用"?"來標註,同時在閉包給出預設值:

Route::get('user/{name?}', function ($name = null) {
    return $name;
});
Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

對於傳入的引數,可以通過正規表示式來判斷輸入是否有效:

Route::get('user/{name}', function ($name) {
    //
})
->where('name', '[A-Za-z]+');

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]+']);
除了直接在路由之後直接進行正則校驗之外,Laravel還提供了設定全域性引數校驗的方式,只需要在RouteServiceProvider::boot()方法中新增對應的規則即可:

public function boot(Router $router)
{
    $router->pattern('id', '[0-9]+');

    parent::boot($router);
}

所有的引數名為id的引數都會進行RouteServiceProvider::boot()中的校驗。

RouteServiceProvider::class主要進行兩件事的操作:1.繫結路由引數校驗;2.為當前請求設定路由。


Laravel還提供了命名路由的功能,除了通過給出的匹配規則外還可以為路由命名:

Route::get('user/profile', ['as' => 'profile', function () {
    //
}]);
或者

Route::get('user/profile', [
    'as' => 'profile', 'uses' => 'UserController@showProfile'
]);
或者

Route::get('user/profile', 'UserController@showProfile')->name('profile');
繫結之後訪問user/profile和訪問profile的內容將會是一致的。


當你給一個路由命名之後,你可能會在檢視或者其他的路由或者控制器使用到當前路由,便可以通過:

$url = route('profile');

$redirect = redirect()->route('profile');

進行重定向。

對於帶有引數的路由,則可以通過:

Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {
    //
}]);

$url = route('profile', ['id' => 1]);

這樣來生成對應的URL。


路由組

對於一個路由組,可以使用鍵值對陣列來宣告一系列按照順序執行的中介軟體,並且適用於組內的所有路由:

Route::group(['middleware' => 'auth'], function () {
    Route::get('/', function ()    {
        // Uses Auth Middleware
    });

    Route::get('user/profile', function () {
        // Uses Auth Middleware
    });
});

同時可以使用鍵值對陣列來宣告組內路由遵循的名稱空間:

Route::group(['namespace' => 'Admin'], function()
{
    // Controllers Within The "App\Http\Controllers\Admin" Namespace

    Route::group(['namespace' => 'User'], function()
    {
        // Controllers Within The "App\Http\Controllers\Admin\User" Namespace
    });
});


這裡有一個注意點:

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to the controller routes in your routes file.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'App\Http\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @param  \Illuminate\Routing\Router  $router
     * @return void
     */
    public function boot(Router $router)
    {
        //

        parent::boot($router);
    }

    /**
     * Define the routes for the application.
     *
     * @param  \Illuminate\Routing\Router  $router
     * @return void
     */
    public function map(Router $router)
    {
        $router->group(['namespace' => $this->namespace], function ($router) {
            require app_path('Http/routes.php');
        });
    }
}

App\Providers\RouteServiceProvider::class的原始碼中顯而易見的包含了引數$namespace,並且在對映路由的時候已經包含了Http/routes.php,也就是說,如果你的路由的名稱空間都是App\Http\Controllers,那麼就不需要設定路由名稱空間引數了,對於名稱空間與之不同的路由再進行設定即可。




相關文章