【laravel】 複雜表單請求驗證類,實現一個類對應多個表單
一、序言
laravel 中提供了兩種驗證請求資料的方法,第一種方法適用於簡單的驗證,表單驗證和業務邏輯放在一起,顯得業務程式碼臃腫,而且重複的驗證規則基本也是複製貼上,程式碼也不好看,這是關鍵。本篇教程就不說這個了,需要了解的請戳這裡。第二種就是建立請求驗證類,下面就詳細說一說這個。(本文只介紹了介面驗證和返回錯誤處理,form表單提交可以看文章底部參考文章中的第一個連結)。
二、正文
表單請求是包含驗證邏輯的自定義請求類,要建立表單驗證類,可以使用
Artisan
命令make:request
,我們可以先建立一個基類,然後建立對應的表單類。
ps:生成的類檔案預設是在app/Http/Requests
目錄下
建立命令如下:
// 建立基類
php artisan make:request BaseRequest
// 系統配置的表單驗證類,建立成功後需要手動修改下讓它繼承基類
php artisan make:request SystemConfigRequest
BaseRequest.php
基類裡面的authorize
方法裡面預設return false
,這個方法是判定使用者是否有許可權發起請求的,我們一般都不會在這個地方判斷請求許可權吧,所以給他改成預設返回true
,如果你有啥特殊需求的話就可以在這裡驗證許可權。
程式碼如下:
<?php
namespace App\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BaseRequest extends FormRequest
{
/**
* @var 當前表單驗證使用的規則
*/
protected $useRules = [];
// 各種驗證規則的錯誤提示,當你子類裡面添加了新的規則這裡也需要加上,或者在子類複寫該變數
protected $errorMsg = [
'required' => '為必填項',
'min' => '最小為:min',
'max' => '最大為:max',
'between' => '長度在:min和:max之間',
'integer' => '必須為整數',
'string' => '必須為字串',
'regex' => '格式錯誤',
'unique' => '已存在',
'present' => '欄位值可以為空但是必傳',
'array' => '必須是陣列格式',
'json' => '不是有效的json格式',
];
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* messages 返回給前臺的錯誤資訊轉換成自定義提示,預設提示是英文
* @return array
*/
public function messages()
{
$array = [];
foreach ($this->useRules as $key => $value) {
// 獲取單個欄位的多個驗證規則
if (!is_array($value))
$new_arr = explode('|', $value);
else
$new_arr = $value;
foreach ($new_arr as $k => $v) {
// 獲取單個規則的前部分
$v = array_first(explode(':', $v));
// 最終得到每個欄位對應的規則返回訊息
$array[$key . '.' . $v] = ':attribute' . $this->errorMsg[$v];
}
}
return $array;
}
}
SystemConfigRequest.php
系統配置請求驗證類裡面可以定義新增,修改等操作的請求資料驗證的規則,其中config.*.title
的寫法是驗證請求過來的陣列中的欄位,實際驗證欄位是config[0][title]
。還有使用 regex 模式時,規則必須放在陣列中,而不能使用管道分隔符,尤其是正則表示式中已經使用了管道符號時。驗證規則有許多,就不一一介紹了,有需要的話可以去看下文件。《 [ Laravel 5.5 文件 ] 處理使用者請求 —— 請求表單驗證及錯誤處理大全 》。
下面看下系統配置請求驗證類怎麼寫的,程式碼如下:
<?php
namespace App\Requests;
// 這裡要繼承上面建立的 BaseRequest 基類哦,別忘了
class SystemConfigRequest extends BaseRequest
{
/**
* @var array 定義驗證規則
*/
private $rules = [
// 這裡代表建立表單需要驗證的欄位
'create' => [
'testCreate' => 'required'
],
// 更新表單需要驗證的欄位
'update' => [
'testUpdate' => 'required'
],
// 不管是建立還是更新都要驗證的欄位
'edit' => [
'config.*.title' => 'required|string',
'config.*.details' => 'present',
'config.*.set_key' => 'required|string',
'config.*.set_value' => 'present',
'token' => 'required|string',
],
];
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
// 根據不同的請求, 新增不同的驗證規則,將對應的請求的規則和公共的規則合併
if (static::getPathInfo() == '/api/system/setconfig')
{
$this->useRules = array_merge($this->rules['create'], $this->rules['edit']);
}
if (static::getPathInfo() == '/api/system/editconfig')
{
$this->useRules = array_merge($this->rules['update'], $this->rules['edit']);
}
return $this->useRules;
}
/**
* attributes 設定各個欄位的中文註解
* @return array
* @author liuml <[email protected]>
* @DateTime 2018/9/13 20:34
*/
public function attributes()
{
return [
'token' => '令牌',
'config' => '配置項',
'config.*.title' => '配置項中標題',
'config.*.details' => '配置項中詳情',
'config.*.set_key' => '配置項中設定的鍵名',
'config.*.set_value' => '配置項中設定的鍵值',
];
}
}
控制器中需要使用的時候,直接注入就行了
/**
* addConfig
* @param SystemConfigRequest $request
* @return \Illuminate\Http\JsonResponse
* @throws BusinessExceptions
*/
public function addConfig(SystemConfigRequest $request){
$config = $request->post();
$res = $this->systemConfigLogic->setConfig($config);
if($res){
return $this->returnData(1);
}
return $this->returnData(0);
}
下面這張圖返回的錯和上面的驗證規則不是匹配的,懶得換對應的圖了,反正知道返回的錯是這樣的就行,當然下圖的返回錯誤是處理過後返回的。至於如何處理的話看結尾的圖例
自定義返回格式啥的在
app\Exceptions\Handler
這裡處理就行。
在render
方法中新增下面程式碼就行,當然你是沒有returnData
方法的。自己封裝一個響應的函式就行。或者直接使用laravel
中的response
函式就行
// 判斷該異常是否是引數驗證錯誤的異常,是的話直接返回
if ($exception instanceof ValidationException) {
$error = array_first(array_collapse($exception->errors()));
return returnData(20000, $error);
}
參考文章:
https://www.jianshu.com/p/0225e63454e8
https://laravelacademy.org/post/7978.html