最適合入門的Laravel初級教程(五)

最適合入門的Laravel初級教程(五)

路由咱會建立了;

控制器也有了;
接下來要搞的就是把二者關聯起來了;
最適合入門的laravel初級教程(三)
咱們講過 Route 的 get 或者 post 方法第一個參數就是咱們要定義的路由;
就是咱們在地址欄請求的那段url;
第二個參數能夠是一個閉包函數;
裏面寫請求定義的路由時執行的內容;
上篇文章咱們說過;
若是把代碼都放這個閉包函數中是臃腫且難以維護的;
因此就須要使用控制器了;
很顯然;控制器就是來替代這第二個參數的閉包函數的;
寫起來也很是簡單直接寫控制器名便可;
而後用 @ 符號分割控制器和控制器的方法php

Route::get('article/index', 'ArticleController@index');
Route::get('article/create', 'ArticleController@create');
Route::post('article/store', 'ArticleController@store');


能夠在控制器中寫點內容;

訪問定義的路由就能夠看到內容了;

一切都是這麼的完美;
可是若是你和我同樣帥;
額;不是;
若是你和我同樣懶且善於總結思考;
你會發現這三條路由都是以 article/ 爲前綴的;
在路由中咱們應該怎麼減小這種重複呢?
這就是咱們接着要講的分組的概念;
路由組就是把一些有相同特性的路由放在一個組裏面;
咱們先來定義一個前綴路由組;
上面這3條路由就能夠改形成這個樣子了;laravel

Route::prefix('article')->group(function () {
    Route::get('index', 'ArticleController@index');
    Route::get('create', 'ArticleController@create');
    Route::post('store', 'ArticleController@store');
});

隨着項目的擴大;

若是控制器都直接放在 app/Http/Controllers 目錄下的話;
那維護起來也開始略頭疼了;
因而就能夠爲控制器分目錄存放了;
好比說我要建一個 app/Http/Controllers/Admin/ArticleController.php;
再建一個 app/Http/Controllers/Home/ArticleController.php ;
命令行也是能夠加目錄的;數據庫

php artisan make:controller Admin/ArticleController --resource
php artisan make:controller Home/ArticleController --resource

再在新建的控制器中寫點內容加以區分;

這種多級目錄是不須要指明目錄的;
只須要指明相對於app/Http/Controllers 目錄的 namespace 便可;bash

Route::prefix('admin/article')->namespace('Admin')->group(function () {
    Route::get('index', 'ArticleController@index');
    Route::get('create', 'ArticleController@create');
    Route::post('store', 'ArticleController@store');
});

group 是能夠嵌套的;
那麼上面這樣的路由還能夠改造下;閉包

Route::prefix('home')->namespace('Home')->group(function () {
    Route::prefix('article')->group(function () {
        Route::get('index', 'ArticleController@index');
        Route::get('create', 'ArticleController@create');
        Route::post('store', 'ArticleController@store');
    });
});

訪問起來就是這樣的了;

由於 Admin 目錄下咱們還會建立更多的路由器;
因此;咱們應該使用 group 嵌套的這種方式;
好比說咱們再有一個 app/Http/Controllers/Admin/TagController.php;
那路由就是這樣的了;app

Route::prefix('home')->namespace('Home')->group(function () {
    Route::prefix('article')->group(function () {
        Route::get('index', 'ArticleController@index');
        Route::get('create', 'ArticleController@create');
        Route::post('store', 'ArticleController@store');
    });
    Route::prefix('tag')->group(function () {
        Route::get('index', 'TagController@index');
        Route::get('create', 'TagController@create');
        Route::post('store', 'TagController@store');
    });
});

除了文檔上講的這種方式;
其實之前版本的 laravel 還有另外一種定義路由組的方式;ide

Route::group(['prefix'=>'admin', 'namespace'=>'Admin'], function () {
    Route::group(['prefix'=>'article'], function () {
        Route::get('index', 'ArticleController@index');
        Route::get('create', 'ArticleController@create');
        Route::post('store', 'ArticleController@store');
    });
});

就是把 prefix 和 namespace 這些都做爲 group 方法的第一個參數;
不過如今不推薦這種寫法了;
不過由於不少之前的項目都是這樣寫的;
這裏講一下讓童鞋們查看別人之前的項目的時候能理解而不迷茫;函數

到這裏咱們已經學會了如何組織多級目錄了;

爲了講解的簡單;
咱們回到 app/Http/Controllers/ArticleController.php 文件接着往下看;
會發現命令行建立的控制器裏面有個 edit 方法;post

public function edit($id)
{
    //
}

edit 方法有個 $id 參數;
這個參數是幹什麼用的呢?
經過名字咱們很容易就明白這是用來修改數據的;
id 通常又是數據庫的自增字段;
那這就是要修改指定 id 的數據了;
可是這個 id 是哪傳來的呢?
下面就到了講解路由參數的時候了;
定義路由的時候咱們是能夠定義路由參數的;
咱們接着上面的路由加一個 edit 的;測試

Route::prefix('article')->group(function () {
    Route::get('index', 'ArticleController@index');
    Route::get('create', 'ArticleController@create');
    Route::post('store', 'ArticleController@store');
    Route::get('edit/{id}', 'ArticleController@edit');
});

咱們在定義路由的時候用花括號包一個變量名;
那這個變量就能夠直接傳到控制器方法中;
而後在地址欄傳什麼控制器中就能夠接到什麼;
爲了方便測試咱們在這個方法中返回 id ;

public function edit($id)
{
    return '地址欄傳的參數是:'.$id;
}

攜帶着路由參數經過路由訪問這個方法;

這裏面有個容易栽跟頭的地方;
就是控制器中的參數名跟路由參數名不是必須相同的;
也就是說我這樣寫也是能夠的;

public function edit($a)
{
    return '地址欄傳的參數是:'.$a;
}

一個路由參數的時候這倒不會以爲什麼;
一旦定義多個路由參數的時候;
這個坑就真的坑了;

Route::prefix('article')->group(function () {
    // ...
    Route::get('edit/{id}/{name}', 'ArticleController@edit');
});

在控制器中獲取路由參數的時候;

public function edit($name, $id)
{
    return 'id是:' . $id . '<br>name是:' . $name;
}

訪問 http://bjyblog.test/article/edit/666a/白俊遙
在你覺得閉着眼都知道結果的時候;
一隻碩大的幺蛾子飛了過來;

你發現 id 和 name 沒對上;
該敲黑板畫重點了筒子們;
路由參數中的第一個參數對應控制器中的第一個路由參數;
以此類推;
在控制器中路由參數跟參數名是不要緊的;
只跟順序有關;

再個 id 通常都是純數字;
這裏卻傳了字母 ;
咱們應該怎麼約束下 id 呢?
laravel 方方面面都爲咱們考慮到了;
咱們加個 where 就好了;

Route::prefix('article')->group(function () {
    // ...
    Route::get('edit/{id}/{name}', 'ArticleController@edit')->where('id', '[0-9]+');
});

這樣就只能傳數字了;
其實大多的表都是用 id 作主鍵的;
若是每一個路由都手動定義一遍約束;
那也是挺麻煩的;
laravel 又一次方方面面都爲咱們考慮到了;
找到 app/Providers/RouteServiceProvider.php 這個文件;
在 boot 方法中能夠定義全局約束;

public function boot()
{
    Route::pattern('id', '[0-9]+');

    parent::boot();
}

這樣就不須要爲每條帶 id 參數的路由定義約束了;
之後全部帶 id 參數的路由就只能傳數字了;
不懂這個 RouteServiceProvider 的話不要緊不要糾結在這;
就先當是固定用法;
之後慢慢懂;

跟路由參數容易搞混的是請求參數;

路由參數?請求參數?傻傻分不清楚;
舉個栗子;

Route::prefix('article')->group(function () {
    // ...
    Route::get('edit/{id}/{name}', 'ArticleController@edit');
});

bjyblog.test/article/edit/666/白俊遙?music=越過山丘&book=平凡世界
id 和 name 就是路由參數;
music 和 book 就是請求參數;
路由參數的獲取咱們已經會了;
那請求參數怎麼獲取呢?
咱們再回控制器中轉悠轉悠還會發現 update 方法;

public function update(Request $request, $id)
{
    //
}

這個 Request $request 就是咱們用來獲取請求參數的關鍵;
它的意思是向控制器的方法傳一個 $request 它是一個 Request 類;
咱們能夠把咱們的 edit 方法也加個 $request ;

public function edit(Request $request, $id, $name)
    {
        $music = $request->input('music');
        $book = request()->input('book');
        $str = <<<php
id: $id <br>
name: $name <br>
music: $music <br>
book: $book <br>
php;
        return $str;
    }

這個 Request $request 是不會影響路由參數的順序的;
它放前放後都是能夠的;
咱們訪問這個方法並攜帶請求參數;

Request 類有一個 input 方法;
把要獲取的參數名傳給它就能夠了;
我上面示例中還用了個 request() 函數;
它跟 Request $request 效果是同樣的;
$request 能夠方便複用;
因此在控制器中更推薦使用 $request ;
若是傳的請求參數比較多的時候;
這樣一個一個的獲取仍是麻煩;
Request 還有個 all 方法就能夠獲取所有的請求參數;

public function edit(Request $request, $id, $name)
    {
        dump($request->all());
    }

dump 是 laravel 自帶的一個打印函數;
就是 php 自帶的 var_dump 函數的升級版;
打印出來的效果是這樣的;

若是想打印數據並 die 掉可使用 dd() 函數;
若是隻想從一大堆請求參數中獲取指定的請求參數
Request 還有個 only 方法;

public function edit(Request $request, $id, $name)
    {
        dump($request->only('music', 'book'));
    }

那若是想排除某個參數剩下的全要呢?
Request 還有個 except 方法;

public function edit(Request $request, $id, $name)
    {
        dump($request->except('music'));
    }

再次讚美 laravel 的體貼周到;

本文爲白俊遙原創文章,轉載無需和我聯繫,但請註明來自白俊遙博客 https://baijunyao.com

相關文章
相關標籤/搜索