让你的 validate 支持场景验证
前言
目前的 validate 是不支持 scene 类似的策略的,这使我在开发中是相当不便利。
在业务编写的过程中 总结出了 一套目前为止我比较满意的解决方案 分享给大家。
流程说明
- 该方法建立在基类(FormRequest)基础之上
- 方法提交时增加类似 token 或者 method 这样的字段
_scene
标记场景,当然你也可以不标记,因为他支持默认的。 - 默认场景会把 当前 路由名称 当做验证场景名称,当 request 出现了
_scene
时才会被替换 - 匹配子类
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 协议》,转载必须注明作者和本文链接
'state' => ['status'] 这是配置的什么
插个眼