在使用验证器过程中的一些困惑,不知道大家有没有遇到一样的困惑?[最后有贴出个人的解决方式]
问题描述
最近按照文档的说明和给出的示例使用验证器,觉得无论是把验证器代码写在 控制器中,还是根据需要的的功能创建一个表单请求,都觉得很乱。
把验证代码写在控制器中,如果出现需要验证的参数特别多的时候,参数还需要加上规则验证,控制器的代码非常臃肿,而且后期改动起来也非常的麻烦,
UserController.php 控制器
/** * 创建用户信息 */ public function createUserInfo(Request $request, UserService $service) { //参数验证 $params = $request->validate([ 'param_a' => ['required',bail','max:255'], 'param_b' => ['bail','required'], 'param_c' => ['bail', 'required', 'regex:/^(?=.*[0-9].*)(?=.*[A-Z].*)(?=.*[a-z].*).{8}$/'], 'param_d' => ['bail','required','in:1,2,3'], 'param_e' => ['bail','required'], 'param_f' => ['bail','required'], 'param_g' => ['bail','required'], 'param_h' => ['bail','required'], ]); //验证成功后逻辑 。。。。 $service->createUserInfo($params); }
创建一个表单请求,一个控制器方法就得创建一个,当方法越多那创建的验证类也多,比如就一个模块可能有 获取/新增/编辑/删除 每个场景都是验证不同的参数,有的参数在某些场景是必填,有些场景却是选填,这样的话相同模块下得为不同创建创建不同的验证类。
php artisan make:request CreateUserInfoRequest
UserController.php 控制器
/** * 创建用户信息 */ public function createUserInfo(CreateUserInfoRequest $request,UserService $service) { //验证参数 $params = $request->all(); $service->createUserInfo($params); }
CreateUserInfoRequest.php 验证器
/** * 获取应用于该请求的验证规则。 * @return array */ public function rules() { return [ 'param_a' => ['required',bail','max:255'], 'param_b' => ['bail','required'], 'param_c' => ['bail', 'required', 'regex:/^(?=.*[0-9].*)(?=.*[A-Z].*)(?=.*[a-z].*).{8}$/'], 'param_d' => ['bail','required','in:1,2,3'], 'param_e' => ['bail','required'], 'param_f' => ['bail','required'], 'param_g' => ['bail','required'], 'param_h' => ['bail','required'], ]; }
问题解决
于是这边就封装了一个 validation 基类, 在基类中修改了 rules 与 messages,使得自动配置控制器名称,这样既解决了 校验代码放在控制器中的臃肿,又解决了因为方法越多,相同模块下需要创建多个 验证类的问题。
<?php /** * @Desc: 基类验证器 */ namespace App\Validation; use Illuminate\Foundation\Http\FormRequest; class Validation extends FormRequest { /** * @return \string[][] */ public function rules():array { $action = $this->getCurrentAction(); $action = $action ? $action.'Rules' : 'defaultRules'; return call_user_func_array([$this, $action], []); } /** * @return string[] */ public function messages():array { $action = $this->getCurrentAction(); $action = $action ? $action.'Messages' : 'defaultMessages'; return call_user_func_array([$this, $action], []); } /** * 获取当前请求的方法 * @return string */ protected function getCurrentAction():string { $controller = $this->route()->getAction('controller'); $action = ''; if (is_string($controller)){ $handler = strpos($controller,'@') !== false ? explode('@', $controller) : []; $action = !empty($handler) ? end($handler) : $action; } return $action; } }
这样的话,一个控制器只需要定义一个验证器类,控制器中不同的方法需要参数验证,就定义对应方法的验证器方法。
UserController.php 控制器
/** * 创建用户信息 */ public function createUserInfo(UserValidation $validation, UserService $service) { //参数验证 $validation->all(); //逻辑处理 } /** * 编辑用户信息 */ public function editUserInfo(UserValidation $validation, UserService $service) { //参数验证 $validation->all(); //逻辑处理 }
UserValidation.php 验证器
<?php namespace App\Validation; use App\Validation\Validation; class AspNetUsersValidation extends Validation { /** * 创建用户信息验证器 */ public function createUserInfoRules(): array { return [ 'param_b' => ['bail','required'], 'param_c' => ['bail', 'required', 'regex:/^(?=.*[0-9].*)(?=.*[A-Z].*)(?=.*[a-z].*).{8}$/'], 'param_d' => ['bail','required','in:1,2,3'], 'param_e' => ['bail','required'], 'param_f' => ['bail','required'], 'param_g' => ['bail','required'], 'param_h' => ['bail','required'], ]; } /** * 编辑用户信息验证器 */ public function editUserInfoRules(): array { return [ 'param_e' => ['bail','required'], 'param_f' => ['bail','required'], 'param_g' => ['bail','required'], 'param_h' => ['bail','required'], ]; } }
我也有这样的困扰,解决方案和你这个很像,但是我是通过路由名字来进行区分的。