教你修改Laravel FormRequest驗(yàn)證,實(shí)現(xiàn)場(chǎng)景驗(yàn)證

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

下面由laravel教程欄目給大家介紹修改Laravel FormRequest驗(yàn)證,實(shí)現(xiàn)場(chǎng)景驗(yàn)證,希望對(duì)需要的朋友有所幫助!

教你修改Laravel FormRequest驗(yàn)證,實(shí)現(xiàn)場(chǎng)景驗(yàn)證

laravel 中,很多創(chuàng)建和編輯的的接口都是需要做數(shù)據(jù)驗(yàn)證的,對(duì)于數(shù)據(jù)驗(yàn)證一般有2種方方式

  • 在控制器里直接使用Request的validate方法

  • 使用自定義FormRequest類,該類集成自httpRequest

    如果使用第一種方法,會(huì)比較亂,看起來不夠優(yōu)雅

    但是如果使用第二種方式,那么針對(duì)每一種請(qǐng)求都要定義一個(gè)FormRequest

    比如:ArticleStoreRequestArticleUpdateRequest

    但是你會(huì)發(fā)現(xiàn)基本上驗(yàn)證規(guī)則是一樣的,當(dāng)然你可以在控制器方法里只注入一個(gè)Request,但是如果針對(duì)于一個(gè)Model 有多個(gè)Update的那種,比如用戶模塊,修改密碼/修改昵稱/修改頭像/修改地址/修改。。。怎么處理呢

    所以這幾天針對(duì)這種情況,改進(jìn)了下Laravel的Request機(jī)制,加了一個(gè)場(chǎng)景驗(yàn)證

    • 第一步:先創(chuàng)建一個(gè)AbstractRequest的基類
    <?php  namespace AppHttpRequests;  use IlluminateFoundationHttpFormRequest; use IlluminateSupportStr;  /**  * 使用方法:  * Class AbstractRequest  * @package AppHttpRequests  */ class AbstractRequest extends FormRequest {     public $scenes = [];     public $currentScene;               //當(dāng)前場(chǎng)景     public $autoValidate = false;       //是否注入之后自動(dòng)驗(yàn)證     public $extendRules;      public function authorize()     {         return true;     }      /**      * 設(shè)置場(chǎng)景      * @param $scene      * @return $this      */     public function scene($scene)     {         $this->currentScene = $scene;         return $this;     }      /**      * 使用擴(kuò)展rule      * @param string $name      * @return AbstractRequest      */     public function with($name = '')     {         if (is_array($name)) {             $this->extendRules = array_merge($this->extendRules[], array_map(function ($v) {                 return Str::camel($v);             }, $name));         } else if (is_string($name)) {             $this->extendRules[] = Str::camel($name);         }          return $this;     }      /**      * 覆蓋自動(dòng)驗(yàn)證方法      */     public function validateResolved()     {         if ($this->autoValidate) {             $this->handleValidate();         }     }      /**      * 驗(yàn)證方法      * @param string $scene      * @throws IlluminateAuthAccessAuthorizationException      * @throws IlluminateValidationValidationException      */     public function validate($scene = '')     {         if ($scene) {             $this->currentScene = $scene;         }         $this->handleValidate();     }      /**      * 根據(jù)場(chǎng)景獲取規(guī)則      * @return array|mixed      */     public function getRules()     {         $rules = $this->container->call([$this, 'rules']);         $newRules = [];         if ($this->extendRules) {             $extendRules = array_reverse($this->extendRules);             foreach ($extendRules as $extendRule) {                 if (method_exists($this, "{$extendRule}Rules")) {   //合并場(chǎng)景規(guī)則                     $rules = array_merge($rules, $this->container->call(                         [$this, "{$extendRule}Rules"]                     ));                 }             }         }         if ($this->currentScene && isset($this->scenes[$this->currentScene])) {             $sceneFields = is_array($this->scenes[$this->currentScene])                 ? $this->scenes[$this->currentScene] : explode(',', $this->scenes[$this->currentScene]);             foreach ($sceneFields as $field) {                 if (array_key_exists($field, $rules)) {                     $newRules[$field] = $rules[$field];                 }             }             return $newRules;         }         return $rules;     }      /**      * 覆蓋設(shè)置 自定義驗(yàn)證器      * @param $factory      * @return mixed      */     public function validator($factory)     {         return $factory->make(             $this->validationData(), $this->getRules(),             $this->messages(), $this->attributes()         );     }      /**      * 最終驗(yàn)證方法      * @throws IlluminateAuthAccessAuthorizationException      * @throws IlluminateValidationValidationException      */     protected function handleValidate()     {         if (!$this->passesAuthorization()) {             $this->failedAuthorization();         }         $instance = $this->getValidatorInstance();         if ($instance->fails()) {             $this->failedValidation($instance);         }     }  }
    • 第二步:針對(duì)用戶Request,我們只需要定義一個(gè)UserRequest繼承AbstractRequest
    <?php  namespace AppHttpRequests;  class UserRequest extends AbstractRequest {   public $scenes = [       'nickname' => 'nickname',       'avatar' => 'avatar',       'password' => 'password',       'address' => 'province_id,city_id'   ];    public function rules()   {       return [        //全部的驗(yàn)證規(guī)則           'mobile' => [],           'nickname' => [],           'password' => [               'required', 'min:6', 'max:16'           ],           'avatar' => [],           'province_id' => [],           'city_id' => [],           //...       ];   }    public function passwordRules()   {       return [           'password' => [               'required', 'min:6', 'max:16', 'different:$old_password'      //修改新密碼不和舊密碼相同,此處只是舉例子,因?yàn)槊艽a需要Hash處理才能判斷是否相同           ]       ];   } }
    • 控制器方法 UserController
    <?php  namespace AppHttpControllers;  use AppHttpRequestsUserRequest;  class UserController {      public function register(UserRequest $request)     {         $request->validate();   //默認(rèn)不設(shè)置場(chǎng)景 全部驗(yàn)證         //...     }      public function updateAddress($id, UserRequest $request)     {         $request->scene('address')->validate();         //...     }      public function updateAvatar($id, UserRequest $request)     {         $request->validate('avatar');         //...     }      public function updatePassword($id, UserRequest $request)     {         //設(shè)置password場(chǎng)景,只驗(yàn)證password字段,并且使用新的password規(guī)則替換原來的password規(guī)則         $request->scene('password')             ->with('password')             ->validate();         //...     } }

    該方法沒有修改Laravel的核心驗(yàn)證邏輯,只讓在FormRequest在注入到Controller的時(shí)候不要做自動(dòng)驗(yàn)證,當(dāng)然,如果需要自動(dòng)驗(yàn)證,那么設(shè)置$autoValidate = true即可。以上內(nèi)容僅供參考。望輕噴。同時(shí)還有我也修改了ORM的場(chǎng)景驗(yàn)證規(guī)則,可以在model里設(shè)置經(jīng)常,同時(shí)滿足多場(chǎng)景創(chuàng)建和更新

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊7 分享