1. 程式人生 > >【laravel】 複雜表單請求驗證類,實現一個類對應多個表單

【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);
}

下面這張圖返回的錯和上面的驗證規則不是匹配的,懶得換對應的圖了,反正知道返回的錯是這樣的就行,當然下圖的返回錯誤是處理過後返回的。至於如何處理的話看結尾的圖例
postman

自定義返回格式啥的在 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