后台Laravel提供的自动表单验证请求类,通常一个类应用于一个Action,虽然可以应用于多个Action,但是校验参数很少说完全一样,并且粒度过大具体来说,如果一个Controller有10个Action,那么对应的要创建10个验证规则类,会导致文件过多,可以封装Request,把粒度从Action改成Controller级别的粒度,这样一个Controller只使用Createaformrequestclass,效果如下,结果一致:原来的验证方式创建验证规则app/Http/Requests├──Requests│├──DeleteBlog.php│├──StoreBlog.php│└──UpdateBlog.php放在文件命名空间App\Http\Requests;useIlluminate\Foundation\Http\FormRequest;classStoreBlogRequestextendsFormRequest{publicfunctionrules(){return['title'=>'required|max:100','content'=>'required|max:1000'];}publicfunctionmessages(){return[];}}classUpdateBlogRequestextendsFormRequest{publicfunctionrules(){return['id'=>'required|integer','title'=>'required|max:100','content'=>'required|max:1000'];}公共赋函数消息(){返回[];}}classDeleteBlogRequestextendsFormRequest{publicfunctionrules(){return['id'=>'required|integer',];}publicfunctionmessages(){return[];}}使用验证规则app/Http/Comtrollers/PostControllernamespaceApp\Http\Controllers;useApp\Http\Requests\DeleteBlogRequest;useApp\Http\Requests\StoreBlogRequest;useApp\Http\Requests\UpdateBlogRequest;classPostsController{publicfunctionstore(StoreBlogRequest$request){/*...*/}publicfunctionupdate(UpdateBlogRequest$request){/*...*/}publicfunctiondelete(DeleteBlogRequest$request){/*...*/}}问题3每个接口对应StoreBlogRequestUpdateBlogRequestDeleteBlogRequest,30个接口对应30个XxxRequest文件太多封装的思想是一个Controller对应一个Request,Request标识需要返回的Rules,达到效果classBlogControllerextendsController{//BlogRequest自动校验store规则publicfunctionstore(BlogRequest$request){/*...*/}//BlogRequest自动验证更新规则publicfunctionupdate(BlogRequest$request){/*...*/}//BlogRequest自动验证删除规则publicfunctiondelete(BlogRequest$request){/*...*/}}implementationmethodnamespaceApp\Http\Requests;classBlogRequestextendsFormRequest{publicfunctionrules(){//获取请求对应的ActionMethod();例如存储/更新/删除$actionMethod=$this->route()->getActionMethod();如果(!method_exists($this,$actionMethod)){返回[];}//例如$this->>store();返回$this->$actionMethod();}publicfunctionstore(){return['title'=>'required|max:100','content'=>'required|max:1000'];}publicfunctiondelete(){返回rn['id'=>'required|integer',];这样,通过定义一个Request规则就可以定义一个Controller了,但是接下来的问题来了,如何定义一个自定义的消息授权呢?根据上面的实现方法,可以抽象出一个BaseRequest继承FormRequest重写相应的方法,然后自定义一个Request继承BaseRequest专注于定义校验规则。BaseRequestclassBaseRequestextendsFormRequest{publicfunctionauthorize():bool{$actionMethod=$this->route()->getActionMethod().'授权';如果(!method_exists($this,$actionMethod)){返回真;}返回$this->$actionMethod();}publicfunctionrules():array{$actionMethod=$this->route()->getActionMethod().'规则';如果(!method_exists($this,$actionMethod)){返回[];}返回$this->$actionMethod();}publicfunctionmessages():array{$actionMethod=$this->route()->getActionMethod()。'消息';如果(!method_exists($this,$actionMethod)){返回[];}返回$this->$actionMethod();}}如您所见,在BaseRequest中,方法实现为ActionMethod+rulesBlogRequestclassBlogRequestextendsBaseRequest{publicfunctionstoreRules(){return['title'=>'required|max:100','content'=>'必需|最大:1000'];}publicfunctionstoreMessages(){return['title.required'=>'标题不能为空','content.required'=>'内容不能为空'];}publicfunctionupdateRules(){return['id'=>'required|integer','title'=>'max:100','content'=>'max:1000'];}publicfunctiondeleteRules(){return['id'=>'required|integer',];}publicfunctiondeleteAuthorize(){返回false;}}BolgControllerclassBlogControllerextendsController{//BlogRequest自动校验存储规则publicfunctionstore(BlogRequest$request){/*...*/}//BlogRequest自动校验更新规则publicfunctionupdate(BlogRequest$request){returnresponse()->json(['status'=>200,'message'=>'success',],200,[],JSON_UNESCAPED_UNICODE);}//BlogRequest自动验证删除规则publicfunctiondelete(BlogRequest$request){/*...*/}}开始服务验证:phpartisanserve$curl-s-d'title=test'-XPOST'127.0.0.1:8000/api/博客/之后/存储'|jq.{"status":400,"message":"内容不能为空"}$curl-s-d'id=1'-XPOST'127.0.0.1:8000/api/blog/after/update'|jq.{"status":200,"message":"success"}$curl-s-d'id=1'-XPOST'127.0.0.1:8000/api/blog/after/delete'|jq.{"status":403,"message":"Youdonothavepermissiontoaccess"//为什么消息是这样的,下面会说}当然也可以在BaseReqeust等定义错误返回格式/**参数验证失败返回处理*/protectedfunctionfailedValidation(Validator$validator):HttpResponseException{$actionMethod=$this->route()->getActionMethod().'FailedValidation';//使用自定义的错误格式,但通常不会在具体的规则类中重写,因为错误格式应该是一致的//可能在特殊情况下需要重写,比如与外部系统交互Methodif(method_exists($this,$actionMethod)){$this->$actionMethod();}//默认错误格式$err=$validator->errors()->first();thrownewHttpResponseException(response()->json(['status'=>400,'message'=>$err,],400,[],JSON_UNESCAPED_UNICODE));}当请求授权验证失败/**时请求授权验证失败(授权方法返回false;失败)*/protectedfunctionfailedAuthorization(){$actionMethod=$this->route()->getActionMethod().'授权失败';如果(method_exists($this,$actionMethod)){返回$this->$actionMethod();}thrownewHttpResponseException(response()->json(['status'=>403,'message'=>'Youdonothavepermissiontoaccess',],403,[],JSON_UNESCAPED_UNICODE));}总结这种方式一个Controller可以对应一个Request,但是有利也有弊,减少了numberoffiles和brings即修改对应规则时,需要找到对应的规则failedValidation和failedAuthorization。统一的返回错误格式也可以通过判断它们的Exception来实现,因为它们抛出的异常分别是ValidationException和AuthorizationException。文档只能看简单的使用方法。遇到问题就去上层看看源码,找一些其他的解决办法。代码。php│├──BlogRequest.php│├──DeleteBlogRequest.php│├──StoreBlogRequest.php│└──UpdateBlogRequest.phpRoute$phpartisanroute:list|grep“博客”发布|api/博客/之后/删除POSTapi/博客/之后/存储POST|api/博客/之后/更新POST|api/博客/之前/deletePOST|api/博客/之前/存储POST|api/blog/before/updategithub.comhttps://github。com/zxr615/rewrite-pay-module/tree/main/app/Http/Controllers
