Laravel实现表单验证(多场景,适用于API)
针对Laravel 的表单验证不支持scene场景验证而做的对应调整。
本篇我们以简易留言板API代码为基准,需要验证的参数包含
title 标题 content 留言内容 id 留言ID 用于修改删除留言
新建BaseRequest类在 App\Http\Requests\
作为验证类的基础类
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Str;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;
/**
* 使用方法:
* Class AbstractRequest
* @package App\Http\Requests
*/
class BaseRequest extends FormRequest
{
public $scenes = [];
public $currentScene; //当前场景
public $autoValidate = false; //是否注入之后自动验证
public function authorize()
{
return true;
}
/**
* 设置场景
* @param $scene
* @return $this
*/
public function scene($scene)
{
$this->currentScene = $scene;
return $this;
}
/**
* 覆盖自动验证方法
*/
public function validateResolved()
{
if ($this->autoValidate) {
$this->handleValidate();
}
}
/**
* 验证方法
* @param string $scene
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Illuminate\Validation\ValidationException
*/
public function validate($scene = '')
{
if ($scene) {
$this->currentScene = $scene;
}
$this->handleValidate();
}
/**
* 根据场景获取规则
* @return array|mixed
*/
public function getRules()
{
$rules = $this->container->call([$this, 'rules']);
$newRules = [];
if ($this->currentScene && isset($this->scenes[$this->currentScene])) {
$sceneFields = is_array($this->scenes[$this->currentScene])
? $this->scenes[$this->currentScene] : explode(',', $this->scenes[$this->currentScene]);
foreach ($sceneFields as $field) {
if (array_key_exists($field, $rules)) {
$newRules[$field] = $rules[$field];
}
}
return $newRules;
}
return $rules;
}
/**
* 覆盖设置 自定义验证器
* @param $factory
* @return mixed
*/
public function validator($factory)
{
return $factory->make(
$this->validationData(), $this->getRules(),
$this->messages(), $this->attributes()
);
}
/**
* 最终验证方法
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Illuminate\Validation\ValidationException
*/
protected function handleValidate()
{
$instance = $this->getValidatorInstance();
if ($instance->fails()) {
$this->failedValidation($instance);
}
$this->passedValidation();
}
/**
* 重写报错部分-适应API JSON下发的需求
*/
protected function failedValidation(Validator $validator)
{
$error= $validator->errors()->all();
throw new HttpResponseException(response()->json(['code'=>505,'msg'=>$error['0'],'data'=>[]]));
}
}
创建留言板验证类-目录同上
<?php
namespace App\Http\Requests;
class MsgBoardRequest extends BaseRequest
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'id'=>'required',
'title' => 'required|max:10',
'content' => 'required|max:255',
];
}
/**
* 获取已定义验证规则的错误消息
*
* @return array
*/
public function messages()
{
return [
'id.required'=>'ID不能为空',
'title.max' =>'标题太长了,简化一下吧',
'title.required' => '标题不能为空',
'content.max' => '内容太多了',
'content.required' => '内容不能为空',
];
}
public $scenes = [
'addMsg' => ['title', 'content'],
'deleteMsg' =>['id']
];
}
创建控制器
引入验证
use App\Http\Requests\MsgBoardRequest;
使用验证
public function addMsg(MsgBoardRequest $request){
$request->validate('addMsg');
}
public function deleteMsg(MsgBoardRequest $request){
$request->validate('deleteMsg');
}