Home >PHP Framework >Laravel >Teach you how to modify Laravel FormRequest verification and implement scenario verification
The following tutorial column will introduce to you how to modify Laravel FormRequest verification and implement scenario verification. I hope it will be helpful to friends in need!
In Laravel, many interfaces created and edited require data verification. There are generally two methods for data verificationUse the validate method of Request directly in the controller
Use the custom
FormRequestIf you use the first method, it will be messy and not elegant enoughBut if you use the second method, then a FormRequest must be defined for each request
For example:
ArticleStoreRequestand
ArticleUpdateRequestBut you will find that the validation rules are basically the same. Of course, you can only inject one in the controller method Request, but if there are multiple Updates for a Model, such as user module, change password/modify nickname/modify avatar/modify address/modify. . . How to deal with itSo in response to this situation in the past few days, Laravel's Request mechanism has been improved and a scenario verification has been added
The first step: Create aBase class of 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); } } }Step 2: For user Request, we only need to define a
<?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处理才能判断是否相同 ] ]; } }Controller method
<?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(); //... } }This method does not modify the core validation logic of Laravel, only allows the injection in the FormRequest Do not do automatic verification when you get to the Controller. Of course, if you need automatic verification, just set
The above content is for reference only. Hope light spray. At the same time, I also modified the scene verification rules of ORM, which can be set frequently in the model to satisfy the creation and update of multiple scenes at the same time
The above is the detailed content of Teach you how to modify Laravel FormRequest verification and implement scenario verification. For more information, please follow other related articles on the PHP Chinese website!