laravel表單驗證的文件寫的比較雜亂無章,在此總結歸納一下
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
class TestRequest extends FormRequest
{
/**
* 表示驗證器是否應在第一個規則失敗時停止
* 注意此處是停止所有屬性與規則,與停止單個屬性的bail規則不同
*
* @var bool
*/
protected $stopOnFirstFailure = false;
/**
* 確定使用者是否有權提出此請求
* 可以在該處做許可權判斷,比如使用者發表帖子,可以在此處判斷使用者是否有權發帖
*
* @return bool
*/
public function authorize(): bool
{
// 例子
$registerTimestamp = strtotime(Auth::user()->created_at);
if( (time() - $registerTimestamp) < 86400 ){
//註冊時間不足24小時,禁止發表新帖子
return false;
}
return true;
}
/**
* 要驗證的資料,可省略,預設值 request()->all()
*/
public function validationData()
{
return [
'title' => '不像我只會心疼哥哥',
'content' => '哥哥,你女朋友要是知道我倆吃同一個棒棒糖,你女朋友不會吃醋吧!',
'password' => '88888888',
];
}
/**
* 驗證規則
*/
public function rules(): array
{
return [
'title' => 'required|between:8,50',
'content' => 'required|min:100',
//假設我們為了使用者安全,發帖時必須提交密碼二次驗證
'password' => 'required|between:6,20',
];
}
/**
* 自定義屬性別名,可省略
*/
public function attributes()
{
return [
'title' => '帖子標題',
'content' => '帖子內容',
];
}
/**
* 自定義錯誤訊息,可省略
*/
public function messages()
{
return [
'required' => ':attribute不能為空, 請填寫後再提交',
'title.between' => '帖子標題長度限制在:min至:max個字之間',
'content.min' => '帖子內容至少需要100個字',
'password.between' => '密碼錯誤', //密碼長度不符合規則,直接返回密碼錯誤,節省資料庫查詢
];
}
/**
* 行內驗證器
* 也許你在yii2和thinkphp中經常這樣用且十分好用, 但是laravel中無法實現,請參考驗證器閉包文件代替
*
* laravel驗證器閉包
* @link https://learnku.com/docs/laravel/10.x/validation/14856#bf0dbb
*
* yii行內驗證器
* @link https://www.yiiframework.com/doc/guide/2.0/zh-cn/input-validation#inline-validators
*
* tp自定義驗證規則
* @link https://doc.thinkphp.cn/v8_0/validator.html
*/
public function validateTitle($attribute, $value, $fail)
{
return ;
}
/**
* 配置驗證器例項。
*
* @param \Illuminate\Validation\Validator $validator
* @return void
*/
public function withValidator(\Illuminate\Validation\Validator $validator)
{
// 這裡是驗證器的後置操作
$validator->after(function (\Illuminate\Validation\Validator $validator) {
/**
* errors 具體內容可以參考 Illuminate\Support\MessageBag
*/
if( $validator->errors()->isEmpty() ){
/**
* 執行到 isEmpty() 時,表示rules裡面的驗證規則都透過了
* 此時密碼只進行了rules裡的規則驗證,我們需要繼續驗證密碼是否與持久儲存相同
*/
$password = $this->input('password');
if( $password !== '123456' ){
$validator->errors()->add('password', '資料庫比對密碼錯誤');
}
}
});
}
/**
*
* 自定義驗證失敗後的錯誤處理
*
* 必需丟擲一個Exception,否則業務程式碼會繼續執行,丟擲了Exception則會被框架捕捉處理
* 直接return返回一個response物件是無效的
*
* 父類 FormRequest 裡面預設丟擲的是 Illuminate\Validation\ValidationException
* 如果是表單請求(application/x-www-form-urlencoded)它會重定向回來源頁面,並且把錯誤資訊寫入flash session,
* 非表單請求否則返回一個固定格式的json響應
*
* 父類預設的failedValidation不能滿足以下需求
* 1、在實際使用中,有的時候我們想驗證失敗時始終返回json而不跳轉,甚至是xml
* 2、預設返回的json格式是固定,而我們可能需要自定義一些json欄位
*
*/
protected function failedValidation(Validator $validator)
{
// 具體內容可以參考 Illuminate\Support\MessageBag
$error = $validator->errors()->all();
// 自定義response物件 Illuminate\Http\Response
$response = response()->json([
//...自定義的錯誤響應內容
'code' => 10001,
'message' => $error->first(),
'errors' => $error->errors(),
]);
/**
* 丟擲一個HttpResponseException異常類,
* 這將阻止驗證器呼叫後的後續程式碼,直接傳送response到瀏覽器
*/
throw new HttpResponseException($response);
}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結