教你修改LaravelFormRequet验证,实现场景验证

2025-07-08 04:00:03 10
  • 收藏
  • 管理
    下面由Laravel教程栏目给大家介绍修改Laravel FormRequest验证,实现场景验证,希望对需要的朋友有所帮助! 在Laravel 中,很多创建和编辑的的接口都是需要做数据验证的,对于数据验证一般有2种方方式 在控制器里直接使用Request的validate方法 使用自定义FormRequest类,该类集成自Http\\\\Request 如果使用第一种方法,会比较乱,看起来不够优雅 但是如果使用第二种方式,那么针对每一种请求都要定义一个FormRequest 比如:ArticleStoreRequest和ArticleUpdateRequest 但是你会发现基本上验证规则是一样的,当然你可以在控制器方法里只注入一个Request,但是如果针对于一个Model 有多个Update的那种,比如用户模块,修改密码/修改昵称/修改头像/修改地址/修改。。。怎么处理呢 所以这几天针对这种情况,改进了下Laravel的Request机制,加了一个场景验证 第一步:先创建一个AbstractRequest的基类 复制currentScene = $scene;return $this;}/** * 使用扩展rule * @param string $name * @return AbstractRequest */publicfunctionwith($name =){if(is_array($name)){ $this->extendRules = array_merge($this->extendRules[], array_map(function($v){returnStr::camel($v);}, $name));}elseif(is_string($name)){ $this->extendRules[]=Str::camel($name);}return $this;}/** * 覆盖自动验证方法 */publicfunction validateResolved(){if($this->autoValidate){ $this->handleValidate();}}/** * 验证方法 * @param string $scene * @throws \\\\Illuminate\\\\Auth\\\\Access\\\\AuthorizationException * @throws \\\\Illuminate\\\\Validation\\\\ValidationException */publicfunction validate($scene =){if($scene){ $this->currentScene = $scene;} $this->handleValidate();}/** * 根据场景获取规则 * @return array|mixed */publicfunction 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 */publicfunction validator($factory){return $factory->make( $this->validationData(), $this->getRules(), $this->messages(), $this->attributes());}/** * 最终验证方法 * @throws \\\\Illuminate\\\\Auth\\\\Access\\\\AuthorizationException * @throws \\\\Illuminate\\\\Validation\\\\ValidationException */protectedfunction handleValidate(){if(!$this->passesAuthorization()){ $this->failedAuthorization();} $instance = $this->getValidatorInstance();if($instance->fails()){ $this->failedValidation($instance);}}} 第二步:针对用户Request,我们只需要定义一个UserRequest继承AbstractRequest 复制nickname,avatar=>avatar,password=>password,address=>province_id,city_id];publicfunction rules(){return[//全部的验证规则mobile=>[],nickname=>[],password=>[required,min:6,max:16],avatar=>[],province_id=>[],city_id=>[],//...];}publicfunction passwordRules(){return[password=>[required,min:6,max:16,different:$old_password//修改新密码不和旧密码相同,此处只是举例子,因为密码需要Hash处理才能判断是否相同]];}} 控制器方法 UserController 复制validate();//默认不设置场景 全部验证//...}publicfunction updateAddress($id,UserRequest $request){ $request->scene(address)->validate();//...}publicfunction updateAvatar($id,UserRequest $request){ $request->validate(avatar);//...}publicfunction updatePassword($id,UserRequest $request){//设置password场景,只验证password字段,并且使用新的password规则替换原来的password规则 $request->scene(password)->with(password)->validate();//...}} 该方法没有修改Laravel的核心验证逻辑,只让在FormRequest在注入到Controller的时候不要做自动验证,当然,如果需要自动验证,那么设置$autoValidate = true即可。 以上内容仅供参考。望轻喷。 同时还有我也修改了ORM的场景验证规则,可以在model里设置经常,同时满足多场景创建和更新
    上一页:教你免费当主机域名经销商Reellercluter篇 下一页:教你使用优化的概念进行网站推广
    全部评论(0)