在 Laravel 中處理請求驗證的智慧方法

Summerm發表於2019-09-19

Laravel

“中世紀盔甲中的男人的黑白肖像,準備揮劍。”作者:亨利·胡斯塔瓦

Laravel是網路工匠的PHP框架。這有助於我們構建強大的應用程式和API。很多人都知道有很多方法可以驗證Laravel中的請求。處理請求驗證是任何應用程式中非常重要的部分。Laravel有一些很好的功能,可以很好地處理這個問題。

我們大多數人都熟悉在控制器中使用驗證器。這是處理傳入請求驗證的最常用方法。

以下是我們的驗證器的樣子 UserController

<?php

namespace App\Http\Controllers\API\v1\Users;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Entities\Models\User;

class UserController extends Controller
{
    public function store(Request $request)
    {

        // validate incoming request

        $validator = Validator::make($request->all(), [
           'email' => 'required|email|unique:users',
           'name' => 'required|string|max:50',
           'password' => 'required'
       ]);

       if ($validator->fails()) {
            Session::flash('error', $validator->messages()->first());
            return redirect()->back()->withInput();
       }

       // finally store our user

    }
}

在控制器中驗證

在控制器中驗證傳入請求沒有任何問題,但這不是最好的方法,你的控制器看起來很亂。在我看來,這是不好的做法。控制器應該只處理來自路由的一個處理請求並返回適當的響應。

在控制器中編寫驗證邏輯將打破單一責任原則。我們都知道需求會隨著時間的推移而變化,每次需求變更時,您的班級職責也會發生變化。因此,在單一班級中承擔很多責任使得管理變得非常困難。

Laravel具有表單請求,一個包含驗證邏輯的單獨請求類。要建立一個,您可以在Artisan命令下使用。

php artisan make:請求UserStoreRequest

這將建立新的Request類 app\Http\Request\UserRequest

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserStoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'required|email|unique:users',
            'name' => 'required|string|max:50',
            'password' => 'required'
        ];
    }

     /**
     * Custom message for validation
     *
     * @return array
     */
    public function messages()
    {
        return [
            'email.required' => 'Email is required!',
            'name.required' => 'Name is required!',
            'password.required' => 'Password is required!'
        ];
    }
}

Laravel Form Request類有兩個預設方法auth()rules()auth()無論當前使用者是否被允許請求,您都可以在方法中執行任何授權邏輯。在rules()方法中,您可以編寫所有驗證規則。還有一種方法messages()可以傳遞自己的驗證訊息陣列。

現在改變我們UserController使用我們UserStoreRequest.你可以輸入提示我們的請求類,它會在呼叫我們的控制器函式之前自動解析和驗證。

<?php

namespace App\Http\Controllers\API\v1\Users;

use App\Http\Controllers\Controller;
use App\Http\Requests\UserStoreRequest;

class UserController extends Controller
{
    public function store(UserStoreRequest $request)
    {
        // Will return only validated data

        $validated = $request->validated();
    }
}

所以我們的控制器現在很纖薄,易於維護。現在我們的控制器不需要擔心任何驗證邏輯。我們有自己的驗證類,只有一個責任來處理驗證,讓控制器在那裡工作。

如果驗證失敗,它會將使用者重定向到上一個位置並顯示錯誤。取決於您的請求型別錯誤訊息將在會話中閃爍。如果請求是AJAX,則將返回帶有422狀態程式碼的響應,並返回JSON格式的錯誤。


通過清理輸入來保持您的應用程式和使用者的安全。在您的應用程式中使用清潔劑,它將確保資料始終格式良好且一致。在許多情況下,由於愚蠢的格式錯誤,驗證失敗。

使用者輸入的行動電話號碼為+ 99-9999-999999+ 99-(9999) - (999999)。這是非常常見的錯誤,我們不能強迫我們的使用者再次重新輸入相同的細節。

其他一些例子是使用者輸入的電子郵件為Foo@Bar.COMFOO@Bar.com。或者輸入名字和姓氏,如FOO **bARfoo baR**

Sanitizer包含在提供給驗證器之前以通用格式轉換和過濾資料的方法。

我正在使用Waavi/Sanitizer包含許多過濾器的包。

讓我們BaseFormRequest為Form Request 建立抽象類,並SanitizesInput在這裡使用trait。

<?php

namespace App\Http\Requests;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;
use Waavi\Sanitizer\Laravel\SanitizesInput;

abstract class BaseFormRequest extends FormRequest
{
    use ApiResponse, SanitizesInput;

    /**
     * For more sanitizer rule check https://github.com/Waavi/Sanitizer
     */
    public function validateResolved()
    {
        {
            $this->sanitize();
            parent::validateResolved();
        }
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    abstract public function rules();

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    abstract public function authorize();

}

所以現在我們可以寫UserStoreRequest下面的內容。從我們的基類擴充套件您的表單請求,因此我們不必在所有請求類中包含特徵。

<?php

namespace App\Http\Requests;

class UserStoreRequest extends BaseFormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'required|email|unique:users',
            'name' => 'required|string|max:50',
            'password' => 'required'
        ];
    }

    public function messages()
    {
        return [
            'email.required' => 'Email is required!',
            'name.required' => 'Name is required!',
            'password.required' => 'Password is required!'
        ];
    }

    /**
     *  Filters to be applied to the input.
     *
     * @return array
     */
    public function filters()
    {
        return [
            'email' => 'trim|lowercase',
            'name' => 'trim|capitalize|escape'
        ];
    }

}

SanitizesInputtrait提供了一種filters()在提供給驗證器之前格式化我們的請求資料的方法。filters()方法返回有效過濾器的陣列。在這裡,我們將使用者電子郵件轉換為小寫並修剪相同的方式將名稱轉換為大寫並轉義任何HTML標記。

您可以從此處詳細瞭解可用的過濾器。

首先,似乎沒有必要為所有人制作單獨的請求類。但是想象一下將所有驗證邏輯放在同一個控制器中。這就像是一場糟糕的噩夢 - 當它來管理你的程式碼時,如果其他人必須管理它,那就更糟了?。

謝謝你的閱讀。
我想聽聽你對此的看法。如果您有任何問題或建議,請留下以下評論。

祝你有美好的一天。

相關文章