Laravel FormRequest 検証を変更し、シナリオ検証を実装する方法を説明します。

藏色散人
リリース: 2020-09-10 11:11:25
転載
3463 人が閲覧しました

#次のチュートリアル列では、Laravel FormreQuestの検証を変更し、シナリオ検証を実装する方法を紹介します。困っている友人に役立つことを願っています。 #Laravel では、作成および編集された多くのインターフェイスでデータ検証が必要です。データ検証には通常 2 つの方法があります

Laravel FormRequest 検証を変更し、シナリオ検証を実装する方法を説明します。

validate を使用します。コントローラーで直接 Request メソッドを使用します。

  • Http\Request

  • から統合されたカスタム

    FormRequest クラスを使用します。最初の方法を使用すると、煩雑で十分エレガントではありませんしかし、2 番目の方法を使用する場合は、リクエストごとに FormRequest を定義する必要があります

    例:

    ArticleStoreRequest

    ArticleUpdateRequest

    ただし、検証ルールは基本的に同じであることがわかります。もちろん、コントローラー メソッドの Request に挿入できるのは 1 つだけですが、複数ある場合は、ユーザーモジュールなどのモデルの更新では、パスワードの変更/ニックネームの変更/アバターの変更/アドレスの変更/変更が行われます。 。 。対処方法そこで、ここ数日のこの状況に対応して、Laravelのリクエスト機構が改善され、シナリオ検証が追加されました

    最初のステップ: 作成a

    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);
              }
          }
      
      }
      ログイン後にコピー
    • ステップ 2: ユーザー リクエストの場合、UserRequest
    • Inheritance
    AbstractRequest## を定義するだけです。
    • #
      <?php
      
      namespace App\Http\Requests;
      
      class UserRequest extends AbstractRequest
      {
        public $scenes = [
            &#39;nickname&#39; => '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处理才能判断是否相同
                ]
            ];
        }
      }
      ログイン後にコピー
      Controller メソッド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 へのインジェクション コントローラーに到達したときに自動検証を行わないでください。もちろん、自動検証が必要な場合は、$autoValidate = true を設定するだけです。
    上記の内容は参考用です。希望の光スプレー。

    同時に、ORM のシーン検証ルールも変更しました。これは、複数のシーンを同時に作成および更新できるようにモデル内で頻繁に設定できます。

    以上がLaravel FormRequest 検証を変更し、シナリオ検証を実装する方法を説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    関連ラベル:
    ソース:learnku.com
    このウェブサイトの声明
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
    最新の問題
    人気のチュートリアル
    詳細>
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート