多数据校验 - CheckStruct
CheckStruct
的使用方式同CheckMap
,除了第一个参数为struct类型
的结构体对象(也可以是对象指针)。
Note |
---|
注意哟,大家常问的问题。struct 的属性会有默认值 ,在某些情况下会引起required 规则的失效,因此根据实际情况配合多种规则(例如min 规则)一起校验会是一个比较严谨的做法。此外,也可以将属性改为指针类型,例如*int 、*float64 等。 |
接口文档: https://godoc.org/github.com/gogf/gf/util/gvalid
Code Block |
---|
|
func CheckStruct(ctx context.Context, object interface{}, rules interface{}, msgs ...CustomMsg) Error |
校验方法也可以使用校验对象的链式操作方法来替代,包方法CheckStruct
等同于以下链式操作方式:
Code Block |
---|
|
g.Validator().Ctx(ctx).Rules(rules).Messages(customErrorMessages).CheckStruct(object) |
示例1,使用map
指定规则及提示信息
Code Block |
---|
|
package main
import ( |
"context"
"github.com/gogf/gf/frame/g"
|
"github.com/gogf/gf/util/gvalid"
)
func main() {
|
Object Age int
}
}
rules := map[string]string |
: "required|length:6,16",
|
: msgs messages := map[string]interface{} |
: objObject // 也可以是指针
// obj := &Object{Name : "john"}
if e if err := gvalid.CheckStruct( |
objcontext.TODO(), user, rules, |
msgse e *
输出:
// {
// "Age": {
// "between": "年龄为18到30周岁"
// },
// "Name": {
// "length": "名称长度为6到16个字符"
// }
|
}
*/
在以上示例中,Age
属性由于默认值0
的存在,因此会引起required
规则的失效,因此这里没有使用required
规则而是使用between
规则来进行校验。
示例2,使用gvalid tag
绑定规则及错误信息
使用gvalid tag
设置的规则,其校验结果是顺序性的。
Code Block |
---|
|
package main
import ( |
"context"
"github.com/gogf/gf/frame/g"
|
"github.com/gogf/gf/util/gvalid"
)
type User struct {
|
Uid int `v:"uid @integer|min: |
1 Name string `v:"name @required|length:6,30#请输入用户名称|用户名称长度非法"`
|
Pass1 string `v:"password1@required|password3"`
|
Pass2 string `v:"password2@required|password3|same: |
password1#Pass2#|密码格式不合法|两次密码不一致,请重新输入"`
}
func main() {
|
Name : if e := gvalid.CheckStruct(context.TODO(), user, nil); e != nil {
|
Maps // 自定义校验规则和错误提示,对定义的特定校验规则和错误提示进行覆盖
|
rules := map[string]string |
:= map[string]interface{} |
eerr := gvalid.CheckStruct(context.TODO(), user, rules, msgs); |
e eMaps
可以看到,我们可以对在struct
定义时使用了gvalid
的标签属性(gvalid tag
)来绑定校验的规则及错误提示信息,规则如下:
[属性别名@]校验规则[#错误提示]
可以看到,CheckStruct
和CheckMap
的gvalid tag
规则是一样的,不过在字段的含义上有一点点小区别:
属性别名
和 错误提示
为非必需字段,校验规则
是必需字段;必需字段。属性别名
非必需字段,指定在校验中使用的对应struct
属性的别名,同时校验成功后的map
中的也将使用该别名返回,例如在处理请求表单时比较有用,因为表单的字段名称往往和struct
的属性名称不一致;的属性名称不一致。错误提示
非必需字段,表示自定义的错误提示信息,当规则校验时对默认的错误提示信息进行覆盖;
在此示例代码中,same:password1
规则同使用same:Pass2
规则是一样的效果。也就是说,在数据校验中,可以同时使用原有的struct
属性名称,也可以使用别名。但是,返回的结果中只会使用别名返回,这也是别名最大的用途。此外,在使用属性名称,也可以使用别名。但是,返回的结果中只会使用别名返回,这也是别名最大的用途。此外,在使用CheckStruct
方法对struct
对象进行校验时,也可以传递校验或者和错误提示参数,这个时候会覆盖struct
在定义时绑定的对应参数。
以上示例执行后,输出结果为:
{
"name "length用户名称长度非法"
},
"password2": {
"password3": "密码格式不合法,密码格式为任意6-18位的可见字符,必须包含大小写字母、数字和特殊字符",
"same": "两次密码不一致,请重新输入"
},
"uid": {
"min": "字段最小值为1"
}
}
{
"name": {
请输入用户ID"
}
},
{
"name": {
"length": "用户名称长度非法"
}
},
{
"password2": {
"password3": "密码格式不合法"
}
}
]
[
{
"name": {
"length": "用户名称长度非法"
|
},
,
"same": "字段值不合法"
},
"uid": {
"min": "字段最小值为6"
}
}
示例3,结构体嵌套校验
gvalid.CheckStruct
支持嵌套的(embedded
)结构体校验,即如果属性也是结构体,并且结构体的属性带有gvalid
标签,无论多深的嵌套层级,这些属性都将被根据设定的规则进行校验。
使用示例:
Code Block |
---|
|
package main
import (
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/util/gvalid"
)
func main() {
type Pass struct {
Pass1 string `valid:"password1@required|same:password2#请输入您的密码|您两次输入的密码不一致"`
Pass2 string `valid:"password2@required|same:password1#请再次输入您的密码|您两次输入的密码不一致"`
}
type User struct {
Pass
Id int
Name string `valid:"name@required#请输入您的姓名"`
}
user := &User{
Name: "john",
Pass: Pass{
Pass1: "1",
Pass2: "2",
},
}
err := gvalid.CheckStruct(user, nil)
g.Dump(err.Maps())
} |
执行后,终端输出:
{
"password1": {
"same": "您两次输入的密码不一致"
},
"password2": {
"same": "您两次输入的密码不一致"
}
}
多数据校验 - CheckStructWithParamMap
为了避免结构体默认值带来的困惑,从goframe v1.16
版本开始,我们增加了一个新的结构体校验方法CheckStructWithParamMap
,用于结构体校验时严格按照给定的map
参数而不是读取结构体的属性值,而校验规则同样会自动读取结构体中的gvalid tag
。我们来看一个示例,我们将之前的示例进行简单的修改:
可选校验规则
当给定的数据校验规则中不包含required*
规则时,表示该规则不是一个必须规则,当属性值为nil
或者空字符串
时,将会忽略其校验。
示例1,空字符串
type Params struct {
Page int `v:"required|min:1 # page is required"`
Size int `v:"required|between:1,100 # size is required"`
ProjectId string `v:"between:1,10000 # project id must between :min, :max"`
}
obj := &Params{
Page: 1,
Size: 10,
}
err := gvalid.CheckStruct(obj, nil)
fmt.Println(err)
// Output:
// <nil>
示例2,空指针属性
type Params struct {
Page int `v:"required|min:1 # page is required"`
Size int `v:"required|between:1,100 # size is required"`
ProjectId *gvar.Var `v:"between:1,10000 # project id must between :min, :max"`
}
obj := &Params{
Page: 1,
Size: 10,
}
err := gvalid.CheckStruct(obj, nil)
fmt.Println(err)
// Output:
// <nil>
示例3,空整型属性
需要注意的是,如果键值为0
或者false
,将仍然会被校验。
type Params struct {
Page int `v:"required|min:1 # page is required"`
Size int `v:"required|between:1,100 # size is required"`
ProjectId int `v:"between:1,10000 # project id must between :min, :max"`
}
obj := &Params{
Page: 1,
Size: 10,
}
err := gvalid.CheckStruct(obj, nil)
fmt.Println(err)
// Output:
// project id must between 1, 10000