让你的 validate 支持场景验证

前言

目前的 validate 是不支持 scene 类似的策略的,这使我在开发中是相当不便利。

在业务编写的过程中 总结出了 一套目前为止我比较满意的解决方案 分享给大家。

流程说明

  1. 该方法建立在基类(FormRequest)基础之上
  2. 方法提交时增加类似 token 或者 method 这样的字段_scene标记场景,当然你也可以不标记,因为他支持默认的。
  3. 默认场景会把 当前 路由名称 当做验证场景名称,当 request 出现了_scene时才会被替换
  4. 匹配子类 scene 场景数组 返回特定的 验证规则 rule

代码部分

<?php

namespace App\Http\Requests;


use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;

class Base extends FormRequest
{

    /**
     * 验证场景
     *
     * @var string
     */
    public $scene = [];

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Create the default validator instance.
     *
     * @param  \Illuminate\Contracts\Validation\Factory  $factory
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function createDefaultValidator(ValidationFactory $factory)
    {

        return $factory->make(
            $this->validationData(), $this->getSceneRules(),
            $this->messages(), $this->attributes()
        );
    }

    /**
     * 获取场景验证规则
     *
     * @return array
     */
    protected function getSceneRules()
    {
        return $this->handleScene($this->container->call([$this, 'rules']));
    }

    /***
     * 基于路由名称的场景验证
     *
     * @param array $rule
     * @return array
     */
    public function handleScene(array $rule)
    {

        $arr = [];

        foreach (($scene = $this->scene[$this->getSceneName()] ?? []) as $item){
            if( isset($rule[$item])){
                $arr[$item] = $rule[$item];
            }
        }

        return  $arr ?: $rule;
    }

    /**
     * 获取场景名称
     *
     * @return string
     */
    public function getSceneName()
    {
        return $this->input('_scene', $this->route()->getName());
    }

    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    public function validationData()
    {
        return $this->all();
    }
}

如何使用

<?php
// +----------------------------------------------------------------------
// | Do what we can do
// +----------------------------------------------------------------------
// | Date  : 2019/12/10 - 4:46 PM
// +----------------------------------------------------------------------
// | Author: seebyyu <seebyyu@gmail.com> :)
// +----------------------------------------------------------------------


namespace App\Http\Requests;

class RoleRequest extends Base
{

    public $scene = [
        'user.role.update' => ['id', 'name', 'status'],
        'user.role.update.state' => ['id', 'status'],
        'user.role.store' => ['name', 'status'],
    ];

    public function rules()
    {
        return [
            'id' => 'required',
            'name' => 'required',
            'status' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'id.required' =>  '请选择角色',
            'name.required' =>  '请填写角色名称',
            'status.required' =>  '请选择启用状态',
        ];
    }

控制器部分代码演示

class RoleController{

    public function update(RoleRequest $request)
    {

        switch ($request->getSceneName()){
            default:
            case 'user.role.update':
                // 修改全部信息
                break;
            case 'user.role.update.state':
                // 修改状态
                break;
        }

        return success();
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
i@llons.com
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 3

'state' => ['status'] 这是配置的什么

1年前 评论
seebyyu (楼主) 1年前
wangyou (作者) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!