天天看點

3分鐘短文:Laravel表單驗證的“指揮中心”:FormRequest

引言

上一章我們學習到,Laravel控制器内引入 ValidatesRequests trait,進而使得繼承了基類控制器的類擁有了驗證器的所有方法。

但是無論在控制器内進行驗證,還是前置到路由器内驗證,都會加重這些區域的代碼重量,特别是對于複雜的驗證邏輯,甚至使得控制器或者路由功能不那麼純粹。

3分鐘短文:Laravel表單驗證的“指揮中心”:FormRequest

那麼有沒有什麼好的設計方法,把資料驗證獨立出來,統一管理,重複利用,不要寫那麼多臃腫的代碼呢?這就是本文我們重點要介紹的 FormRequest 表單請求類。

代碼時間

聲明一個表單請求類,使用指令行腳手架可以輕松完成:

php artisan make:request CreateCommentRequest           

建立的檔案位于 app/Http/Requests/CreateCommentRequest.php。為了與修改後的代碼有個對比,我們把預設的檔案内容貼在下方:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CreateCommentRequest extends FormRequest
{
    public function authorize()
    {
        return false;
    }

    public function rules()
    {
        return [];
    }
}           

注意表單請求類預設繼承了 FormRequest 類,預設的方法有兩個:

第一個是 authorize 用于驗證是否有權限使用該驗證器,示例中始終傳回 false,也就是說任何調用,都不被允許,系統傳回 403 狀态碼。

第二個方法是 rules,用于傳回一個驗證規則組成的數組。這個規則的寫法,與上一章我們介紹的規則方法毫無二緻。

下面我們根據業務邏輯,首先修改 authorize 方法,滿足以下兩個條件,才允許驗證:

  • 必須登入狀态
  • 使用者必須釋出過文章

下面是代碼的實作:

public function authorize()
{
    $blogPostId = $this->route('blogPost');
    
    if (! auth()->check()) {
        return false;
    }
    
    $isExisted = BlogPost::where('id', $blogPostId)->exists();
    if (! $isExisted) {
        return false;
    }
        
    return true;
}           

大家看到了吧,在驗證器内可以橫向使用模型資料查詢,來進行資料一緻性判斷。其中還有一個潛在的知識點要說一下,就是代碼開頭的那個 $this->route() 方法,其實是用來擷取路由綁定參數的方法。這要求我們在路由注冊裡,有類似下面這樣的條目:

Route::post('blogPosts/{blogPost}', function () {  })           

使用路由位置參數綁定傳遞的值,可以使用 $this->route()方法讀取,這與 get/post 方法的擷取有所不同,大家要記得區分。

好了,授權做完了,下面該驗證規則上場了,一旦通過驗證的資料進入到驗證環節,就要執行 rules 方法内定義的規則,我們修改代碼如下:

public function rules()
{
    return [
        'body' => 'required|max:1000'
    ];
}           

這隻是一個示例啊,大家将就看一看,更多驗證規則在文檔或者源碼裡,有詳細的說明。

完成上述的表單請求類之後,就可以在代碼内引入使用了。最簡單的,在路由檔案内使用依賴注入執行個體化該類:

Route::post('blogPosts/{blogPost}/comment', function (App\Http\Requests\CreateCommentRequest $request) {
    // 存儲資料
});           

這條路由是我們上述代碼中示範位置參數 blogPost 時引入了,我們在執行方法中引入了表單請求類,laravel自動會将請求資料代入到該類内執行驗證。

我們使用 FormRequest 改造驗證方法之後,不僅引入了資源的權限判斷,還把驗證規則獨立出來,可用于獨立維護,或者集中管控,是不是友善多了?

寫在最後

本文用了一個對部落格文章建立評論内容的方法,将驗證規則在 FormRequest 内實作。我們完全可以從最後一個寫作方法中延伸出更多的花樣玩法,大家可以去github借鑒大神的寫法,學習更多技巧。

Happy coding :-)

我是 @程式員小助手 ,專注程式設計知識,圈子動态的IT領域原創作者