日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

教你修改Laravel FormRequest验证,实现场景验证

發布時間:2023/12/29 综合教程 32 生活家
生活随笔 收集整理的這篇文章主要介紹了 教你修改Laravel FormRequest验证,实现场景验证 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面由Laravel教程欄目給大家介紹修改Laravel FormRequest驗證,實現場景驗證,希望對需要的朋友有所幫助!

在Laravel 中,很多創建和編輯的的接口都是需要做數據驗證的,對于數據驗證一般有2種方方式

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

使用自定義FormRequest類,該類集成自Http\\Request

如果使用第一種方法,會比較亂,看起來不夠優雅

但是如果使用第二種方式,那么針對每一種請求都要定義一個FormRequest

比如:ArticleStoreRequest和ArticleUpdateRequest

但是你會發現基本上驗證規則是一樣的,當然你可以在控制器方法里只注入一個Request,但是如果針對于一個Model 有多個Update的那種,比如用戶模塊,修改密碼/修改昵稱/修改頭像/修改地址/修改。。。怎么處理呢

所以這幾天針對這種情況,改進了下Laravel的Request機制,加了一個場景驗證

第一步:先創建一個AbstractRequest的基類

<?php

namespace App\\Http\\Requests;

use Illuminate\\Foundation\\Http\\FormRequest;
use Illuminate\\Support\\Str;

/**
 * 使用方法:
 * Class AbstractRequest
 * @package App\\Http\\Requests
 */
class AbstractRequest extends FormRequest
{
    public $scenes = [];
    public $currentScene;               //當前場景
    public $autoValidate = false;       //是否注入之后自動驗證
    public $extendRules;

    public function authorize()
    {
        return true;
    }

    /**
     * 設置場景
     * @param $scene
     * @return $this
     */
    public function scene($scene)
    {
        $this->currentScene = $scene;
        return $this;
    }

    /**
     * 使用擴展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;
    }

    /**
     * 覆蓋自動驗證方法
     */
    public function validateResolved()
    {
        if ($this->autoValidate) {
            $this->handleValidate();
        }
    }

    /**
     * 驗證方法
     * @param string $scene
     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException
     * @throws \\Illuminate\\Validation\\ValidationException
     */
    public function validate($scene = '')
    {
        if ($scene) {
            $this->currentScene = $scene;
        }
        $this->handleValidate();
    }

    /**
     * 根據場景獲取規則
     * @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")) {   //合并場景規則
                    $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;
    }

    /**
     * 覆蓋設置 自定義驗證器
     * @param $factory
     * @return mixed
     */
    public function validator($factory)
    {
        return $factory->make(
            $this->validationData(), $this->getRules(),
            $this->messages(), $this->attributes()
        );
    }

    /**
     * 最終驗證方法
     * @throws \\Illuminate\\Auth\\Access\\AuthorizationException
     * @throws \\Illuminate\\Validation\\ValidationException
     */
    protected function handleValidate()
    {
        if (!$this->passesAuthorization()) {
            $this->failedAuthorization();
        }
        $instance = $this->getValidatorInstance();
        if ($instance->fails()) {
            $this->failedValidation($instance);
        }
    }

}

第二步:針對用戶Request,我們只需要定義一個UserRequest繼承AbstractRequest

<?php

namespace App\\Http\\Requests;

class UserRequest extends AbstractRequest
{
  public $scenes = [
      'nickname' => 'nickname',
      'avatar' => 'avatar',
      'password' => 'password',
      'address' => 'province_id,city_id'
  ];

  public function rules()
  {
      return [        //全部的驗證規則
          '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'      //修改新密碼不和舊密碼相同,此處只是舉例子,因為密碼需要Hash處理才能判斷是否相同
          ]
      ];
  }
}

控制器方法 UserController

<?php

namespace App\\Http\\Controllers;

use App\\Http\\Requests\\UserRequest;

class UserController
{

    public function register(UserRequest $request)
    {
        $request->validate();   //默認不設置場景 全部驗證
        //...
    }

    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)
    {
        //設置password場景,只驗證password字段,并且使用新的password規則替換原來的password規則
        $request->scene('password')
            ->with('password')
            ->validate();
        //...
    }
}

該方法沒有修改Laravel的核心驗證邏輯,只讓在FormRequest在注入到Controller的時候不要做自動驗證,當然,如果需要自動驗證,那么設置$autoValidate = true即可。

以上內容僅供參考。望輕噴。

同時還有我也修改了ORM的場景驗證規則,可以在model里設置經常,同時滿足多場景創建和更新

總結

以上是生活随笔為你收集整理的教你修改Laravel FormRequest验证,实现场景验证的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。