Struct校验常使用以下链式操作方式:

  1. g.Validator().Data(object).Run(ctx)

gvalid tag规则介绍

在开始介绍Struct参数类型校验之前,我们来介绍一下常用的gvalid tag规则。规则如下:

  1. [属性别名@]校验规则[#错误提示]

其中:

  • 属性别名错误提示非必需字段校验规则必需字段。
  • 属性别名 非必需字段,指定在校验中使用的对应struct属性的别名,同时校验后返回的error对象中的也将使用该别名返回。例如在处理请求表单时比较有用,因为表单的字段名称往往和struct的属性名称不一致。大部分场景下不需要设置属性别名,默认直接使用属性名称即可。
  • 校验规则则为当前属性的校验规则,多个校验规则请使用|符号组合,例如:required|between:1,100
  • 错误提示 非必需字段,表示自定义的错误提示信息,当规则校验时对默认的错误提示信息进行覆盖。

gvalid tag使用示例

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/os/gctx"
  5. )
  6. type User struct {
  7. Uid int `v:"uid @integer|min:1#|请输入用户ID"`
  8. Name string `v:"name @required|length:6,30#请输入用户名称|用户名称长度非法"`
  9. Pass1 string `v:"password1@required|password3"`
  10. Pass2 string `v:"password2@required|password3|same:Pass1#|密码格式不合法|两次密码不一致,请重新输入"`
  11. }
  12. func main() {
  13. var (
  14. ctx = gctx.New()
  15. user = &User{
  16. Name: "john",
  17. Pass1: "Abc123!@#",
  18. Pass2: "123",
  19. }
  20. )
  21. err := g.Validator().Data(user).Run(ctx)
  22. if err != nil {
  23. g.Dump(err.Items())
  24. }
  25. }

可以看到,我们可以对在struct定义时使用了gvalidgvalid tag来绑定校验的规则及错误提示信息。在此示例代码中,same:password1规则同使用same:Pass1规则是一样的效果。也就是说,在数据校验中,可以同时使用原有的struct属性名称,也可以使用别名。但是,返回的结果中只会使用别名返回,这也是别名最大的用途。此外,在对struct对象进行校验时,也可以传递校验或者和错误提示参数,这个时候会覆盖struct在定义时绑定的对应参数。

以上示例执行后,输出结果为:

  1. [
  2. {
  3. "uid": {
  4. "min": "请输入用户ID",
  5. },
  6. },
  7. {
  8. "name": {
  9. "length": "用户名称长度非法",
  10. },
  11. },
  12. {
  13. "password2": {
  14. "password3": "密码格式不合法",
  15. },
  16. },
  17. ]

使用map指定校验规则

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/os/gctx"
  5. )
  6. func main() {
  7. type User struct {
  8. Age int
  9. Name string
  10. }
  11. var (
  12. ctx = gctx.New()
  13. user = User{Name: "john"}
  14. rules = map[string]string{
  15. "Name": "required|length:6,16",
  16. "Age": "between:18,30",
  17. }
  18. messages = map[string]interface{}{
  19. "Name": map[string]string{
  20. "required": "名称不能为空",
  21. "length": "名称长度为{min}到{max}个字符",
  22. },
  23. "Age": "年龄为18到30周岁",
  24. }
  25. )
  26. err := g.Validator().Rules(rules).Messages(messages).Data(user).Run(ctx)
  27. if err != nil {
  28. g.Dump(err.Maps())
  29. }
  30. }

在以上示例中,Age属性由于默认值0的存在,因此会引起required规则的失效,因此这里没有使用required规则而是使用between规则来进行校验。示例代码执行后,终端输出:

  1. {
  2. "Age": {
  3. "between": "年龄为18到30周岁"
  4. },
  5. "Name": {
  6. "length": "名称长度为6到16个字符"
  7. }
  8. }

结构体递归校验(嵌套校验)

支持递归的结构体校验(嵌套校验),即如果属性也是结构体(也支持嵌套结构体(embedded)),那么将会自动将该属性执行递归校验。使用示例:

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/os/gctx"
  5. )
  6. func main() {
  7. type Pass struct {
  8. Pass1 string `valid:"password1@required|same:password2#请输入您的密码|您两次输入的密码不一致"`
  9. Pass2 string `valid:"password2@required|same:password1#请再次输入您的密码|您两次输入的密码不一致"`
  10. }
  11. type User struct {
  12. Pass
  13. Id int
  14. Name string `valid:"name@required#请输入您的姓名"`
  15. }
  16. var (
  17. ctx = gctx.New()
  18. user = &User{
  19. Name: "john",
  20. Pass: Pass{
  21. Pass1: "1",
  22. Pass2: "2",
  23. },
  24. }
  25. )
  26. err := g.Validator().Data(user).Run(ctx)
  27. g.Dump(err.Maps())
  28. }

或者属性为嵌套结构体(embedded)的场景:

  1. package main
  2. import (
  3. "github.com/gogf/gf/v2/frame/g"
  4. "github.com/gogf/gf/v2/os/gctx"
  5. )
  6. func main() {
  7. type Pass struct {
  8. Pass1 string `valid:"password1@required|same:password2#请输入您的密码|您两次输入的密码不一致"`
  9. Pass2 string `valid:"password2@required|same:password1#请再次输入您的密码|您两次输入的密码不一致"`
  10. }
  11. type User struct {
  12. Id int
  13. Name string `valid:"name@required#请输入您的姓名"`
  14. Pass Pass
  15. }
  16. var (
  17. ctx = gctx.New()
  18. user = &User{
  19. Name: "john",
  20. Pass: Pass{
  21. Pass1: "1",
  22. Pass2: "2",
  23. },
  24. }
  25. )
  26. err := g.Validator().Data(user).Run(ctx)
  27. g.Dump(err.Maps())
  28. }

执行后,终端输出:

  1. {
  2. "password1": {
  3. "same": "您两次输入的密码不一致",
  4. },
  5. "password2": {
  6. "same": "您两次输入的密码不一致",
  7. },
  8. }