一、前言
- 有读者建议我出一个 Lumen 的 自定义表单验证 示例
实际上,官方文档已经很描述得非常详细了。阅读本文的前提是你已经对 Laravel 的 验证 和 本地化 有所掌握
二、开始
因为 Lumen 已经是精简版的缘故,所以框架本身并没有对 表单验证 做过多的处理
默认的,如果沿用 Laravel 中的validator()方法验证错误的表单,将会抛出一个Illuminate\Validation\ValidationException的异常:<?php# Illuminate\Validation\Validator.phppublic function validate(){if ($this->fails()) {throw new ValidationException($this);}return $this->validated();}
既然框架已经抛出异常了,那么我们只要去捕获此类异常,然后根据自定义的格式输出接口,改变原有的渲染方式即可
<?php# App\Exceptions\Handler.phppublic function render($request, Exception $exception){// 拦截表单验证的异常if ($exception instanceof ValidationException) {$errors = $exception->errors();$message = '';// 此处错误信息 $msg 会根据 APP_LOCAL 格式化成自定义的内容foreach ($errors as $key => $msg) {$message .= ($key . ' => ' . implode(' | ', $msg) . ' && ');}return response()->json(['code' => 4000,'message' => rtrim($message, ' && '),'errors' => $errors]);} elseif ($exception instanceof ServerException) { // 拦截自定义服务端的异常return response()->json(['code' => $exception->getCode(),'message' => $exception->getMessage(),]);}return parent::render($request, $exception);}
三、详解
对于复杂的表单提交,如果是在 Laravel 中,通常是去实现一个自定义的请求类:
<?phpnamespace App\Http\Requests;use Illuminate\Foundation\Http\FormRequest;class UserEditRequest extends FormRequest{/*** Determine if the user is authorized to make this request.** @return bool*/public function authorize(){return false;}/*** Get the validation rules that apply to the request.** @return array*/public function rules(){return ['mobile' => 'required|cn_mobile', // cn_mobile 是自定义的验证规则,表示只支持国内手机号'email' => 'required|email','name' => 'required|size:6,12'];}}
但是由于 Lumen 已经精简掉了
Illuminate\Foundation\Http\FormRequest这个类, 所以就没有办法沿用这种方式了
那么换一种思路呢?实际上我们在 中间件 中去处理请求,也是能达到相同的效果:<?phpnamespace App\Http\Middleware;use App\Exceptions\ServerException;use App\Http\Form\Contract AS FormContract;use Closure;class Form{public function handle($request, Closure $next, $v){$class = app('App\\Http\\Form\\' . ucfirst($v));if ($class instanceof FormContract) {$class->handle($request);} else {throw new ServerException(5000);}return $next($request);}}
在 Lumen 中定义好 中间件 后,可以在需要启用表单验证的地方调用即可,例如在任意 控制器 的
__constructor()方法处使用:<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;class User extends Controller{public function __construct(){# 表示只对 edit + create 方法使用 form 中间件# form:user 同时也指定了表单验证类 App\Http\Form\User.php$this->middleware('form:user', ['only' => ['edit', 'create']]);}public function index(){$user = ['name' => 'AdamTyn','email' => 'tynadam@foxmail.com','mobile' => '1888888888',];return response()->json(['data' => $user,'code' => 0]);}public function edit(Request $request){// do somethingsreturn response()->json($request->all());}public function create(Request $request){// do somethingsreturn response()->json($request->all());}}
对于更多的表单,则可以在
App\Http\Form命名空间下继续创建对应的 表单验证类,具体实现可以通过示例 Code 去进一步了解
经过上述一顿操作之后,可以在浏览器熟练地输入对应路由地址,即可看到:{"code": 4000,"message": "mobile => 手机号为必传参数. && email => email不能为空. && name => name不能为空.","errors": {"mobile": ["手机号为必传参数."],"email": ["email不能为空."],"name": ["name不能为空."]}}
眼尖的读者应该发现 (当然我也在前文的注释中悄悄地提及了),我们的错误信息不再只是英文,而是已经出现了更为具体的中文描述了
还记得 前言 中提到的 本地化 吗?也即框架的Illuminate\Validation\ValidationException的异常信息都是会根据设置的语言进行格式化的,默认是使用英语。感兴趣的读者可以自行查看resources/lang目录:

最后放出参考的示例 Code
四、结语
本教程面向新手,更多教程会在日后给出。
- 随着系统升级,软件更新,以后的配置可能有所变化,在下会第一时间测试并且更新教程。
- 欢迎联系在下,讨论建议都可以,之后会发布其它的教程。
