優雅的實現請求類驗證規則的重複利用(無需繼承,可適用於多個請求類的規則合併)

zhaiduting發表於2020-07-24

關鍵程式碼只有一句

類似於這樣
return [...] + @OtherRequest::rules()
如下圖三行描紅程式碼所示(不可以去掉@符號,否則報錯!)
優雅的實現請求類驗證規則的重複利用(無需繼承,可適用於多個請求類的規則合併)

使用Postman測試效果如下圖

名稱、密碼和驗證碼不能為空,這3項報錯資訊是UserRequest類直接提供的。而手機號碼不能為空,這項報錯資訊是“艾特”VerificationCodeRequest這個請求類之後得到的。
優雅的實現請求類驗證規則的重複利用(無需繼承,可適用於多個請求類的規則合併)

對於多個類的情況

關鍵程式碼也只有一句
return [...] + @OtherRequest::rules() + @HisRequest::rules() + @HerRequest::rules() + ...

為什麼不使用array_merge()操縱陣列?

關於A+Barray_merge(A,B)的區別,使用tinker測試一下就清楚了,也可以直接看這張截圖。使用A+B的好處其實就是一個目的:保證優先採用A的驗證規則。如果B裡面的某條驗證規則跟A的有衝突,則B的失效、A有效。

如果想利用父類的驗證規則怎麼辦?

這更簡單,直接使用return [...] + parent::rules()就可以了,連@符號都不需要了。
如果既想用父類規則,也想用其他類規則,可以像下面這樣
return [...] + parent::rules() + @OtherRequest::rules() + ...

跟app(OtherRequest::class)相比有什麼不同?

app(OtherRequest::class)這行程式碼寫在UserRequest類的3個成員函式中的任何一個裡面也都可以實現手機號碼的驗證(點選檢視詳情),但是這個驗證效果是分兩步走的。顯然比不上本文推薦的寫法,本文寫法可以一步到位,無需分步驗證。

貼上截圖1的原始碼

UserRequest類的原始碼如下

<?php

namespace App\Http\Requests\Api;

class UserRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'required|between:2,30',
            'password' => 'required|between:6,20',
            'code' => 'required|between:4,10|alpha_num'
        ] + @VerificationCodeRequest::rules();
    }
    public function attributes()
    {
        return [
            'code' => '簡訊驗證碼'
        ] + @VerificationCodeRequest::attributes();
    }
    public function messages()
    {
        return [] + @VerificationCodeRequest::messages();
    }
}

VerificationCodeRequest類的原始碼如下

class VerificationCodeRequest extends FormRequest
{
    public function rules()
    {
        return [
            'phone' => 'required|unique:users|regex:/^1[^0-2]\d{9}$/'
        ];
    }
    public function attributes()
    {
        return [
            'phone' => '手機號碼'
        ];
    }

    public function messages()
    {
        return [
            'phone.regex' => '手機號碼 不存在'
        ];
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章