美文网首页LumenLaravel开发实践PHP经验分享
Laravel业务篇:接口开发之自定义表单验证

Laravel业务篇:接口开发之自定义表单验证

作者: 我爱余倩 | 来源:发表于2019-02-15 16:43 被阅读0次

    一、前言

    1. 有读者建议我出一个 Lumen自定义表单验证 示例。
    2. 实际上,官方文档已经很描述得非常详细了。阅读本文的前提是你已经对 Laravel验证本地化 有所掌握。

    二、开始

    1. 因为 Lumen 已经是精简版的缘故,所以框架本身并没有对 表单验证 做过多的处理。
      默认的,如果沿用 Laravel 中的 validator() 方法验证错误的表单,将会抛出一个 Illuminate\Validation\ValidationException 的异常:
       # Illuminate\Validation\Validator.php
       public function validate()
       {
           if ($this->fails()) {
               throw new ValidationException($this);
           }
      
           return $this->validated();
       }
      
    2. 既然框架已经抛出异常了,那么我们只要去捕获此类异常,然后根据自定义的格式输出接口,改变原有的渲染方式即可。
       # 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);
       }
      

    三、详解

    1. 对于复杂的表单提交,如果是在 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'
               ];
           }
       }
      
    2. 但是由于 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);
           }
       }
      
    3. 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());
           }
       }
      
    4. 对于更多的表单,则可以在 App\Http\Form 命名空间下继续创建对应的 表单验证类,具体实现可以通过示例 Code 进行了解。
      经过上述一顿操作之后,可以在浏览器熟练地输入对应路由地址:
       {
           "code": 4000,
           "message": "mobile => 手机号为必传参数. && email => email不能为空. && name => name不能为空.",
           "errors": {
               "mobile": [
                   "手机号为必传参数."
               ],
               "email": [
                   "email不能为空."
               ],
               "name": [
                   "name不能为空."
               ]
           }
       }
      
    5. 眼尖的读者应该发现 (当然我也在前文的注释中悄悄地提及了),我们的错误信息不再只是英文,而是已经出现了更为具体的中文描述了。
      还记得 前言 中提到的 本地化 吗?也即框架的 Illuminate\Validation\ValidationException 的异常信息都是会根据设置的语言进行格式化的,默认是使用英语。感兴趣的读者可以自行查看 resources/lang 目录:
    resources/lang
    1. 最后放出参考的示例 Code

    五、结语

    1. 本教程面向新手,更多教程会在日后给出。
    2. 随着系统升级,软件更新,以后的配置可能有所变化,在下会第一时间测试并且更新教程;
    3. 欢迎联系在下,讨论建议都可以,之后会发布其它的教程。

    相关文章

      网友评论

        本文标题:Laravel业务篇:接口开发之自定义表单验证

        本文链接:https://www.haomeiwen.com/subject/nriteqtx.html