一、序言
laravel 中提供了两种验证请求数据的方法,第一种方法适用于简单的验证,表单验证和业务逻辑放在一起,显得业务代码臃肿,而且重复的验证规则基本也是复制粘贴,代码也不好看,这是关键。本篇教程就不说这个了,需要了解的请戳这里。第二种就是建立请求验证类,下面就详细说一说这个。(本文只介绍了接口验证和返回错误处理,form表单提交可以看文章底部参考文章中的第一个链接)。
二、正文
表单请求是包含验证逻辑的自定义请求类,要创建表单验证类,可以使用
Artisan
命令make:request
,我们可以先创建一个基类,然后创建对应的表单类。
ps:生成的类文件默认是在app/Http/Requests
目录下
创建命令如下:
// 创建基类
php artisan make:request BaseRequest
// 系统配置的表单验证类,创建成功后需要手动修改下让它继承基类
php artisan make:request SystemConfigRequest
BaseRequest.php
基类里面的authorize
方法里面默认return false
,这个方法是判定用户是否有权限发起请求的,我们一般都不会在这个地方判断请求权限吧,所以给他改成默认返回true
,如果你有啥特殊需求的话就可以在这里验证权限。
代码如下:
<?php
namespace App\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BaseRequest extends FormRequest
{
/**
* @var 当前表单验证使用的规则
*/
protected $useRules = [];
// 各种验证规则的错误提示,当你子类里面添加了新的规则这里也需要加上,或者在子类复写该变量
protected $errorMsg = [
'required' => '为必填项',
'min' => '最小为:min',
'max' => '最大为:max',
'between' => '长度在:min和:max之间',
'integer' => '必须为整数',
'string' => '必须为字符串',
'regex' => '格式错误',
'unique' => '已存在',
'present' => '字段值可以为空但是必传',
'array' => '必须是数组格式',
'json' => '不是有效的json格式',
];
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* messages 返回给前台的错误信息转换成自定义提示,默认提示是英文
* @return array
*/
public function messages()
{
$array = [];
foreach ($this->useRules as $key => $value) {
// 获取单个字段的多个验证规则
if (!is_array($value))
$new_arr = explode('|', $value);
else
$new_arr = $value;
foreach ($new_arr as $k => $v) {
// 获取单个规则的前部分
$v = array_first(explode(':', $v));
// 最终得到每个字段对应的规则返回消息
$array[$key . '.' . $v] = ':attribute' . $this->errorMsg[$v];
}
}
return $array;
}
}
SystemConfigRequest.php
系统配置请求验证类里面可以定义添加,修改等操作的请求数据验证的规则,其中config.*.title
的写法是验证请求过来的数组中的字段,实际验证字段是config[0][title]
。还有使用 regex 模式时,规则必须放在数组中,而不能使用管道分隔符,尤其是正则表达式中已经使用了管道符号时。验证规则有许多,就不一一介绍了,有需要的话可以去看下文档。《 [ Laravel 5.5 文档 ] 处理用户请求 —— 请求表单验证及错误处理大全 》。
下面看下系统配置请求验证类怎么写的,代码如下:
<?php
namespace App\Requests;
// 这里要继承上面创建的 BaseRequest 基类哦,别忘了
class SystemConfigRequest extends BaseRequest
{
/**
* @var array 定义验证规则
*/
private $rules = [
// 这里代表创建表单需要验证的字段
'create' => [
'testCreate' => 'required'
],
// 更新表单需要验证的字段
'update' => [
'testUpdate' => 'required'
],
// 不管是创建还是更新都要验证的字段
'edit' => [
'config.*.title' => 'required|string',
'config.*.details' => 'present',
'config.*.set_key' => 'required|string',
'config.*.set_value' => 'present',
'token' => 'required|string',
],
];
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
// 根据不同的请求, 添加不同的验证规则,将对应的请求的规则和公共的规则合并
if (static::getPathInfo() == '/api/system/setconfig')
{
$this->useRules = array_merge($this->rules['create'], $this->rules['edit']);
}
if (static::getPathInfo() == '/api/system/editconfig')
{
$this->useRules = array_merge($this->rules['update'], $this->rules['edit']);
}
return $this->useRules;
}
/**
* attributes 设置各个字段的中文注解
* @return array
* @author liuml <liumenglei0211@163.com>
* @DateTime 2018/9/13 20:34
*/
public function attributes()
{
return [
'token' => '令牌',
'config' => '配置项',
'config.*.title' => '配置项中标题',
'config.*.details' => '配置项中详情',
'config.*.set_key' => '配置项中设置的键名',
'config.*.set_value' => '配置项中设置的键值',
];
}
}
控制器中需要使用的时候,直接注入就行了
/**
* addConfig
* @param SystemConfigRequest $request
* @return \Illuminate\Http\JsonResponse
* @throws BusinessExceptions
*/
public function addConfig(SystemConfigRequest $request){
$config = $request->post();
$res = $this->systemConfigLogic->setConfig($config);
if($res){
return $this->returnData(1);
}
return $this->returnData(0);
}
下面这张图返回的错和上面的验证规则不是匹配的,懒得换对应的图了,反正知道返回的错是这样的就行,当然下图的返回错误是处理过后返回的。至于如何处理的话看结尾的图例
自定义返回格式啥的在
app\Exceptions\Handler
这里处理就行。
在render
方法中添加下面代码就行,当然你是没有returnData
方法的。自己封装一个响应的函数就行。或者直接使用laravel
中的response
函数就行
// 判断该异常是否是参数验证错误的异常,是的话直接返回
if ($exception instanceof ValidationException) {
$error = array_first(array_collapse($exception->errors()));
return returnData(20000, $error);
}
参考文章:
https://www.jianshu.com/p/0225e63454e8
https://laravelacademy.org/post/7978.html