一、前言
二、开始
- 因为 Lumen 已经是精简版的缘故,所以框架本身并没有对 表单验证 做过多的处理。
默认的,如果沿用 Laravel 中的validator()
方法验证错误的表单,将会抛出一个Illuminate\Validation\ValidationException
的异常:# Illuminate\Validation\Validator.php public function validate() { if ($this->fails()) { throw new ValidationException($this); } return $this->validated(); }
- 既然框架已经抛出异常了,那么我们只要去捕获此类异常,然后根据自定义的格式输出接口,改变原有的渲染方式即可。
# App\Exceptions\Handler.php public 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 中,通常是去实现一个自定义的请求类:
<?php namespace 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
这个类, 所以就没有办法沿用这种方式了。
那么换一种思路呢?实际上我们在 中间件 中去处理请求,也是能达到相同的效果:<?php namespace 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(4000); } return $next($request); } }
- 在 Lumen 中定义好 中间件 后,可以在需要启用表单验证的地方调用即可,例如在任意 控制器 的
__constructor()
方法处使用:<?php namespace 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 somethings return response()->json($request->all()); } public function create(Request $request) { // do somethings return 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。
五、结语
- 本教程面向新手,更多教程会在日后给出。
- 随着系统升级,软件更新,以后的配置可能有所变化,在下会第一时间测试并且更新教程;
- 欢迎联系在下,讨论建议都可以,之后会发布其它的教程。
网友评论