下面由Laravel教程栏目给大家介绍修改Laravel FormRequest验证,实现场景验证,希望对需要的朋友有所帮助!
在Laravel 中,很多创建和编辑的的接口都是需要做数据验证的,对于数据验证一般有2种方方式
在控制器里直接使用Request的valIDate方法
使用自定义FormRequest类,该类集成自http\Request
如果使用第一种方法,会比较乱,看起来不够优雅
但是如果使用第二种方式,那么针对每一种请求都要定义一个FormRequest
比如:ArticleStoreRequest和ArticleUpdateRequest
但是你会发现基本上验证规则是一样的,当然你可以在控制器方法里只注入一个Request,但是如果针对于一个Model 有多个Update的那种,比如用户模块,修改密码/修改昵称/修改头像/修改地址/修改。。。怎么处理呢
所以这几天针对这种情况,改进了下Laravel的Request机制,加了一个场景验证
第一步:先创建一个AbstractRequest的基类<?PHPnamespace 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
<?PHPnamespace 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
<?PHPnamespace 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验证,实现场景验证全部内容,希望文章能够帮你解决教你修改Laravel FormRequest验证,实现场景验证所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)