gvalid

package
v2.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2026 License: MIT Imports: 25 Imported by: 63

Documentation

Overview

Package gvalid implements powerful and useful data/form validation functionality.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeleteRule

func DeleteRule(rules ...string)

DeleteRule deletes custom defined validation one or more rules and associated functions from global package.

func GetRegisteredRuleMap

func GetRegisteredRuleMap() map[string]RuleFunc

GetRegisteredRuleMap returns all the custom registered rules and associated functions.

func GetTags

func GetTags() []string

GetTags returns the validation tags.

func ParseTagValue

func ParseTagValue(tag string) (field, rule, msg string)

ParseTagValue parses one sequence tag to field, rule and error message. The sequence tag is like: [alias@]rule[...#msg...]

func RegisterRule

func RegisterRule(rule string, f RuleFunc)

RegisterRule registers custom validation rule and function for package.

func RegisterRuleByMap

func RegisterRuleByMap(m map[string]RuleFunc)

RegisterRuleByMap registers custom validation rules using map for package.

Types

type CustomMsg

type CustomMsg = map[string]any

CustomMsg is the custom error message type, like: map[field] => string|map[rule]string

type Error

type Error interface {
	Code() gcode.Code
	Current() error
	Error() string
	FirstItem() (key string, messages map[string]error)
	FirstRule() (rule string, err error)
	FirstError() (err error)
	Items() (items []map[string]map[string]error)
	Map() map[string]error
	Maps() map[string]map[string]error
	String() string
	Strings() (errs []string)
}

Error is the validation error for validation result.

type RuleFunc

type RuleFunc func(ctx context.Context, in RuleFuncInput) error

RuleFunc is the custom function for data validation.

type RuleFuncInput

type RuleFuncInput struct {
	// Rule specifies the validation rule string, like "required", "between:1,100", etc.
	Rule string

	// Message specifies the custom error message or configured i18n message for this rule.
	Message string

	// Field specifies the field for this rule to validate.
	Field string

	// ValueType specifies the type of the value, which might be nil.
	ValueType reflect.Type

	// Value specifies the value for this rule to validate.
	Value *gvar.Var

	// Data specifies the `data` which is passed to the Validator. It might be a type of map/struct or a nil value.
	// You can ignore the parameter `Data` if you do not really need it in your custom validation rule.
	Data *gvar.Var
}

RuleFuncInput holds the input parameters that passed to custom rule function RuleFunc.

type Validator

type Validator struct {
	// contains filtered or unexported fields
}

Validator is the validation manager for chaining operations.

Example (After)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Time1 string
		Time2 string `v:"after:Time1"`
		Time3 string `v:"after:Time1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Time1: "2022-09-01",
			Time2: "2022-09-01",
			Time3: "2022-09-02",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Time2 value `2022-09-01` must be after field Time1 value `2022-09-01`
Example (AfterEqual)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Time1 string
		Time2 string `v:"after-equal:Time1"`
		Time3 string `v:"after-equal:Time1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Time1: "2022-09-02",
			Time2: "2022-09-01",
			Time3: "2022-09-02",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Time2 value `2022-09-01` must be after or equal to field Time1 value `2022-09-02`
Example (Array)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Value1 string   `v:"array"`
		Value2 string   `v:"array"`
		Value3 string   `v:"array"`
		Value4 []string `v:"array"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Value1: "1,2,3",
			Value2: "[]",
			Value3: "[1,2,3]",
			Value4: []string{},
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Value1 value `1,2,3` is not of valid array type
Example (Bail)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Account   string `v:"bail|required|length:6,16|same:QQ"`
		QQ        string
		Password  string `v:"required|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Account:   "gf",
			QQ:        "123456",
			Password:  "goframe.org",
			Password2: "goframe.org",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The Account value `gf` length must be between 6 and 16
Example (BankCard)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		BankCard1 string `v:"bank-card"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			BankCard1: "6225760079930218",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The BankCard1 value `6225760079930218` is not a valid bank card number
Example (Before)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Time1 string `v:"before:Time3"`
		Time2 string `v:"before:Time3"`
		Time3 string
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Time1: "2022-09-02",
			Time2: "2022-09-03",
			Time3: "2022-09-03",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Time2 value `2022-09-03` must be before field Time3 value `2022-09-03`
Example (BeforeEqual)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Time1 string `v:"before-equal:Time3"`
		Time2 string `v:"before-equal:Time3"`
		Time3 string
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Time1: "2022-09-02",
			Time2: "2022-09-01",
			Time3: "2022-09-01",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Time1 value `2022-09-02` must be before or equal to field Time3
Example (Between)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Age1   int     `v:"between:1,100"`
		Age2   int     `v:"between:1,100"`
		Score1 float32 `v:"between:0.0,10.0"`
		Score2 float32 `v:"between:0.0,10.0"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Age1:   50,
			Age2:   101,
			Score1: 9.8,
			Score2: -0.5,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Age2 value `101` must be between 1 and 100
The Score2 value `-0.5` must be between 0 and 10
Example (Boolean)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Boolean bool    `v:"boolean"`
		Integer int     `v:"boolean"`
		Float   float32 `v:"boolean"`
		Str1    string  `v:"boolean"`
		Str2    string  `v:"boolean"`
		Str3    string  `v:"boolean"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Boolean: true,
			Integer: 1,
			Float:   10.0,
			Str1:    "on",
			Str2:    "",
			Str3:    "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Float value `10` field must be true or false
The Str3 value `goframe` field must be true or false
Example (CaseInsensitive)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Account   string `v:"required"`
		Password  string `v:"required|ci|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Account:   "gf",
			Password:  "Goframe.org", // Diff from Password2, but because of "ci", rule check passed
			Password2: "goframe.org",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Example (Date)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Date1 string `v:"date"`
		Date2 string `v:"date"`
		Date3 string `v:"date"`
		Date4 string `v:"date"`
		Date5 string `v:"date"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Date1: "2021-10-31",
			Date2: "2021.10.31",
			Date3: "2021-Oct-31",
			Date4: "2021 Octa 31",
			Date5: "2021/Oct/31",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Date3 value `2021-Oct-31` is not a valid date
The Date4 value `2021 Octa 31` is not a valid date
The Date5 value `2021/Oct/31` is not a valid date
Example (DateFormat)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Date1 string `v:"date-format:Y-m-d"`
		Date2 string `v:"date-format:Y-m-d"`
		Date3 string `v:"date-format:Y-m-d H:i:s"`
		Date4 string `v:"date-format:Y-m-d H:i:s"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Date1: "2021-11-01",
			Date2: "2021-11-01 23:00", // error
			Date3: "2021-11-01 23:00:00",
			Date4: "2021-11-01 23:00", // error
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Date2 value `2021-11-01 23:00` does not match the format: Y-m-d
The Date4 value `2021-11-01 23:00` does not match the format: Y-m-d H:i:s
Example (Datetime)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Date1 string `v:"datetime"`
		Date2 string `v:"datetime"`
		Date3 string `v:"datetime"`
		Date4 string `v:"datetime"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Date1: "2021-11-01 23:00:00",
			Date2: "2021-11-01 23:00",     // error
			Date3: "2021/11/01 23:00:00",  // error
			Date4: "2021/Dec/01 23:00:00", // error
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Date2 value `2021-11-01 23:00` is not a valid datetime
The Date3 value `2021/11/01 23:00:00` is not a valid datetime
The Date4 value `2021/Dec/01 23:00:00` is not a valid datetime
Example (Different)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Name          string `v:"required"`
		MailAddr      string `v:"required"`
		OtherMailAddr string `v:"required|different:MailAddr"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Name:          "gf",
			MailAddr:      "gf@goframe.org",
			OtherMailAddr: "gf@goframe.org",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The OtherMailAddr value `gf@goframe.org` must be different from field MailAddr value `gf@goframe.org`
Example (Domain)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Domain1 string `v:"domain"`
		Domain2 string `v:"domain"`
		Domain3 string `v:"domain"`
		Domain4 string `v:"domain"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Domain1: "goframe.org",
			Domain2: "a.b",
			Domain3: "goframe#org",
			Domain4: "1a.2b",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Domain3 value `goframe#org` is not a valid domain format
The Domain4 value `1a.2b` is not a valid domain format
Example (Email)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		MailAddr1 string `v:"email"`
		MailAddr2 string `v:"email"`
		MailAddr3 string `v:"email"`
		MailAddr4 string `v:"email"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			MailAddr1: "gf@goframe.org",
			MailAddr2: "gf@goframe", // error
			MailAddr3: "gf@goframe.org.cn",
			MailAddr4: "gf#goframe.org", // error
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The MailAddr2 value `gf@goframe` is not a valid email address
The MailAddr4 value `gf#goframe.org` is not a valid email address
Example (Enums)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type Status string
	const (
		StatusRunning Status = "Running"
		StatusOffline Status = "Offline"
	)
	type BizReq struct {
		Id     int    `v:"required"`
		Name   string `v:"required"`
		Status Status `v:"enums"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Id:     1,
			Name:   "john",
			Status: Status("Pending"),
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

	// May Output:
	// The Status value `Pending` should be in enums of: ["Running","Offline"]
}
Example (Eq)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Name      string `v:"required"`
		Password  string `v:"required|eq:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Name:      "gf",
			Password:  "goframe.org",
			Password2: "goframe.net",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The Password value `goframe.org` must be equal to field Password2 value `goframe.net`
Example (Float)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Integer string `v:"float"`
		Float   string `v:"float"`
		Str     string `v:"float"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Integer: "100",
			Float:   "10.0",
			Str:     "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Str value `goframe` is not of valid float type
Example (Foreach)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Value1 []int `v:"foreach|in:1,2,3"`
		Value2 []int `v:"foreach|in:1,2,3"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Value1: []int{1, 2, 3},
			Value2: []int{3, 4, 5},
		}
	)
	if err := g.Validator().Bail().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Value2 value `4` is not in acceptable range: 1,2,3
Example (Gt)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Value1 int
		Value2 int `v:"gt:Value1"`
		Value3 int `v:"gt:Value1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Value1: 1,
			Value2: 1,
			Value3: 2,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Value2 value `1` must be greater than field Value1 value `1`
Example (Gte)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Value1 int
		Value2 int `v:"gte:Value1"`
		Value3 int `v:"gte:Value1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Value1: 2,
			Value2: 1,
			Value3: 2,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Value2 value `1` must be greater than or equal to field Value1 value `2`
Example (In)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID     uint   `v:"required" dc:"Your Id"`
		Name   string `v:"required" dc:"Your name"`
		Gender uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:     1,
			Name:   "test",
			Gender: 3,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The Gender value `3` is not in acceptable range: 0,1,2
Example (Integer)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Integer string `v:"integer"`
		Float   string `v:"integer"`
		Str     string `v:"integer"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Integer: "100",
			Float:   "10.0",
			Str:     "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Float value `10.0` is not an integer
The Str value `goframe` is not an integer
Example (Ip)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		IP1 string `v:"ip"`
		IP2 string `v:"ip"`
		IP3 string `v:"ip"`
		IP4 string `v:"ip"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			IP1: "127.0.0.1",
			IP2: "fe80::812b:1158:1f43:f0d1",
			IP3: "520.255.255.255", // error >= 10000
			IP4: "ze80::812b:1158:1f43:f0d1",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The IP3 value `520.255.255.255` is not a valid IP address
The IP4 value `ze80::812b:1158:1f43:f0d1` is not a valid IP address
Example (Ipv4)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		IP1 string `v:"ipv4"`
		IP2 string `v:"ipv4"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			IP1: "127.0.0.1",
			IP2: "520.255.255.255",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The IP2 value `520.255.255.255` is not a valid IPv4 address
Example (Ipv6)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		IP1 string `v:"ipv6"`
		IP2 string `v:"ipv6"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			IP1: "fe80::812b:1158:1f43:f0d1",
			IP2: "ze80::812b:1158:1f43:f0d1",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The IP2 value `ze80::812b:1158:1f43:f0d1` is not a valid IPv6 address
Example (Json)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		JSON1 string `v:"json"`
		JSON2 string `v:"json"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			JSON1: "{\"name\":\"goframe\",\"author\":\"Guo Qiang\"}",
			JSON2: "{\"name\":\"goframe\",\"author\":\"Guo Qiang\",\"test\"}",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The JSON2 value `{"name":"goframe","author":"Guo Qiang","test"}` is not a valid JSON string
Example (Length)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Length1 string `v:"length:5,12"`
		Length2 string `v:"length:10,15"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Length1: "goframe 欢迎你",
			Length2: "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Length2 value `goframe` length must be between 10 and 15
Example (Lt)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Value1 int
		Value2 int `v:"lt:Value1"`
		Value3 int `v:"lt:Value1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Value1: 2,
			Value2: 1,
			Value3: 2,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Value3 value `2` must be lesser than field Value1 value `2`
Example (Lte)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Value1 int
		Value2 int `v:"lte:Value1"`
		Value3 int `v:"lte:Value1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Value1: 1,
			Value2: 1,
			Value3: 2,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err.String())
	}

}
Output:

The Value3 value `2` must be lesser than or equal to field Value1 value `1`
Example (Mac)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Mac1 string `v:"mac"`
		Mac2 string `v:"mac"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Mac1: "4C-CC-6A-D6-B1-1A",
			Mac2: "Z0-CC-6A-D6-B1-1A",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Mac2 value `Z0-CC-6A-D6-B1-1A` is not a valid MAC address
Example (Max)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Age1   int     `v:"max:100"`
		Age2   int     `v:"max:100"`
		Score1 float32 `v:"max:10.0"`
		Score2 float32 `v:"max:10.0"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Age1:   99,
			Age2:   101,
			Score1: 9.9,
			Score2: 10.1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Age2 value `101` must be equal or lesser than 100
The Score2 value `10.1` must be equal or lesser than 10
Example (MaxLength)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		MaxLength1 string `v:"max-length:11"`
		MaxLength2 string `v:"max-length:5"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			MaxLength1: "goframe 欢迎你",
			MaxLength2: "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The MaxLength2 value `goframe` length must be equal or lesser than 5
Example (Min)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Age1   int     `v:"min:100"`
		Age2   int     `v:"min:100"`
		Score1 float32 `v:"min:10.0"`
		Score2 float32 `v:"min:10.0"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Age1:   50,
			Age2:   101,
			Score1: 9.8,
			Score2: 10.1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Age1 value `50` must be equal or greater than 100
The Score1 value `9.8` must be equal or greater than 10
Example (MinLength)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		MinLength1 string `v:"min-length:10"`
		MinLength2 string `v:"min-length:8"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			MinLength1: "goframe 欢迎你",
			MinLength2: "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The MinLength2 value `goframe` length must be equal or greater than 8
Example (NotEQ)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Name          string `v:"required"`
		MailAddr      string `v:"required"`
		OtherMailAddr string `v:"required|not-eq:MailAddr"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Name:          "gf",
			MailAddr:      "gf@goframe.org",
			OtherMailAddr: "gf@goframe.org",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The OtherMailAddr value `gf@goframe.org` must not be equal to field MailAddr value `gf@goframe.org`
Example (NotIn)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID           uint   `v:"required" dc:"Your Id"`
		Name         string `v:"required" dc:"Your name"`
		InvalidIndex uint   `v:"not-in:-1,0,1"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:           1,
			Name:         "test",
			InvalidIndex: 1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The InvalidIndex value `1` must not be in range: -1,0,1
Example (NotRegex)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Regex1 string `v:"regex:\\d{4}"`
		Regex2 string `v:"not-regex:\\d{4}"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Regex1: "1234",
			Regex2: "1234",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Regex2 value `1234` should not be in regex of: \d{4}
Example (Passport)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Passport1 string `v:"passport"`
		Passport2 string `v:"passport"`
		Passport3 string `v:"passport"`
		Passport4 string `v:"passport"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Passport1: "goframe",
			Passport2: "1356666",  // error starting with letter
			Passport3: "goframe#", // error containing only numbers or underscores
			Passport4: "gf",       // error length between 6 and 18
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Passport2 value `1356666` is not a valid passport format
The Passport3 value `goframe#` is not a valid passport format
The Passport4 value `gf` is not a valid passport format
Example (Password)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Password1 string `v:"password"`
		Password2 string `v:"password"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Password1: "goframe",
			Password2: "gofra", // error length between 6 and 18
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Password2 value `gofra` is not a valid password format
Example (Password2)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Password1 string `v:"password2"`
		Password2 string `v:"password2"`
		Password3 string `v:"password2"`
		Password4 string `v:"password2"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Password1: "Goframe123",
			Password2: "gofra",      // error length between 6 and 18
			Password3: "Goframe",    // error must contain lower and upper letters and numbers.
			Password4: "goframe123", // error must contain lower and upper letters and numbers.
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Password2 value `gofra` is not a valid password2 format
The Password3 value `Goframe` is not a valid password2 format
The Password4 value `goframe123` is not a valid password2 format
Example (Password3)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Password1 string `v:"password3"`
		Password2 string `v:"password3"`
		Password3 string `v:"password3"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Password1: "Goframe123#",
			Password2: "gofra",      // error length between 6 and 18
			Password3: "Goframe123", // error must contain lower and upper letters, numbers and special chars.
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Password2 value `gofra` is not a valid password3 format
The Password3 value `Goframe123` is not a valid password3 format
Example (Phone)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		PhoneNumber1 string `v:"phone"`
		PhoneNumber2 string `v:"phone"`
		PhoneNumber3 string `v:"phone"`
		PhoneNumber4 string `v:"phone"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			PhoneNumber1: "13578912345",
			PhoneNumber2: "17178912345",
			PhoneNumber3: "11578912345", // error 11x not exist
			PhoneNumber4: "1357891234",  // error len must be 11
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The PhoneNumber3 value `11578912345` is not a valid phone number
The PhoneNumber4 value `1357891234` is not a valid phone number
Example (PhoneLoose)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		PhoneNumber1 string `v:"phone-loose"`
		PhoneNumber2 string `v:"phone-loose"`
		PhoneNumber3 string `v:"phone-loose"`
		PhoneNumber4 string `v:"phone-loose"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			PhoneNumber1: "13578912345",
			PhoneNumber2: "11578912345", // error 11x not exist
			PhoneNumber3: "17178912345",
			PhoneNumber4: "1357891234", // error len must be 11
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The PhoneNumber2 value `11578912345` is not a valid phone number
The PhoneNumber4 value `1357891234` is not a valid phone number
Example (Postcode)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Postcode1 string `v:"postcode"`
		Postcode2 string `v:"postcode"`
		Postcode3 string `v:"postcode"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Postcode1: "100000",
			Postcode2: "10000",   // error length must be 6
			Postcode3: "1000000", // error length must be 6
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Postcode2 value `10000` is not a valid postcode format
The Postcode3 value `1000000` is not a valid postcode format
Example (Qq)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		QQ1 string `v:"qq"`
		QQ2 string `v:"qq"`
		QQ3 string `v:"qq"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			QQ1: "389961817",
			QQ2: "9999",       // error >= 10000
			QQ3: "514258412a", // error all number
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The QQ2 value `9999` is not a valid QQ number
The QQ3 value `514258412a` is not a valid QQ number
Example (Regex)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Regex1 string `v:"regex:[1-9][0-9]{4,14}"`
		Regex2 string `v:"regex:[1-9][0-9]{4,14}"`
		Regex3 string `v:"regex:[1-9][0-9]{4,14}"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Regex1: "1234",
			Regex2: "01234",
			Regex3: "10000",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Regex1 value `1234` must be in regex of: [1-9][0-9]{4,14}
The Regex2 value `01234` must be in regex of: [1-9][0-9]{4,14}
Example (RegisterRule)
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gconv"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	type User struct {
		Id   int
		Name string `v:"required|unique-name # 请输入用户名称|用户名称已被占用"`
		Pass string `v:"required|length:6,18"`
	}
	user := &User{
		Id:   1,
		Name: "john",
		Pass: "123456",
	}

	rule := "unique-name"
	gvalid.RegisterRule(rule, func(ctx context.Context, in gvalid.RuleFuncInput) error {
		var (
			id   = in.Data.Val().(*User).Id
			name = gconv.String(in.Value)
		)
		n, err := g.Model("user").Where("id != ? and name = ?", id, name).Count()
		if err != nil {
			return err
		}
		if n > 0 {
			return errors.New(in.Message)
		}
		return nil
	})
	err := g.Validator().Data(user).Run(gctx.New())
	fmt.Println(err.Error())
	// May Output:
	// The Name value `john` is not unique
}
Example (Required)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID   uint   `v:"required"`
		Name string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID: 1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Name field is required
Example (RequiredIf)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID          uint   `v:"required" dc:"Your ID"`
		Name        string `v:"required" dc:"Your name"`
		Gender      uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
		WifeName    string `v:"required-if:gender,1"`
		HusbandName string `v:"required-if:gender,2"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:     1,
			Name:   "test",
			Gender: 1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The WifeName field is required
Example (RequiredIfAll)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID       uint   `v:"required" dc:"Your ID"`
		Name     string `v:"required" dc:"Your name"`
		Age      int    `v:"required" dc:"Your age"`
		MoreInfo string `v:"required-if-all:id,1,age,18" dc:"Your more info"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:   1,
			Name: "test",
			Age:  18,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The MoreInfo field is required
Example (RequiredUnless)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID          uint   `v:"required" dc:"Your ID"`
		Name        string `v:"required" dc:"Your name"`
		Gender      uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
		WifeName    string `v:"required-unless:gender,0,gender,2"`
		HusbandName string `v:"required-unless:id,0,gender,2"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:     1,
			Name:   "test",
			Gender: 1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The WifeName field is required; The HusbandName field is required
Example (RequiredWith)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID          uint   `v:"required" dc:"Your ID"`
		Name        string `v:"required" dc:"Your name"`
		Gender      uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
		WifeName    string
		HusbandName string `v:"required-with:WifeName"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:       1,
			Name:     "test",
			Gender:   1,
			WifeName: "Ann",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The HusbandName field is required
Example (RequiredWithAll)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID          uint   `v:"required" dc:"Your ID"`
		Name        string `v:"required" dc:"Your name"`
		Gender      uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
		WifeName    string
		HusbandName string `v:"required-with-all:Id,Name,Gender,WifeName"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:       1,
			Name:     "test",
			Gender:   1,
			WifeName: "Ann",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The HusbandName field is required
Example (RequiredWithout)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID          uint   `v:"required" dc:"Your ID"`
		Name        string `v:"required" dc:"Your name"`
		Gender      uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
		WifeName    string
		HusbandName string `v:"required-without:Id,WifeName"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			ID:     1,
			Name:   "test",
			Gender: 1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The HusbandName field is required
Example (RequiredWithoutAll)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ID          uint   `v:"required" dc:"Your ID"`
		Name        string `v:"required" dc:"Your name"`
		Gender      uint   `v:"in:0,1,2" dc:"0:Secret;1:Male;2:Female"`
		WifeName    string
		HusbandName string `v:"required-without-all:Id,WifeName"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Name:   "test",
			Gender: 1,
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The HusbandName field is required
Example (ResidentId)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		ResidentID1 string `v:"resident-id"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			ResidentID1: "320107199506285482",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The ResidentID1 value `320107199506285482` is not a valid resident id number
Example (Same)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Name      string `v:"required"`
		Password  string `v:"required|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Name:      "gf",
			Password:  "goframe.org",
			Password2: "goframe.net",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

The Password value `goframe.org` must be the same as field Password2 value `goframe.net`
Example (Size)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Size1 string `v:"size:11"`
		Size2 string `v:"size:5"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Size1: "goframe 欢迎你",
			Size2: "goframe",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Size2 value `goframe` length must be 5
Example (Telephone)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gstr"
)

func main() {
	type BizReq struct {
		Telephone1 string `v:"telephone"`
		Telephone2 string `v:"telephone"`
		Telephone3 string `v:"telephone"`
		Telephone4 string `v:"telephone"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Telephone1: "010-77542145",
			Telephone2: "0571-77542145",
			Telephone3: "20-77542145", // error
			Telephone4: "775421451",   // error len must be 7 or 8
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(gstr.Join(err.Strings(), "\n"))
	}

}
Output:

The Telephone3 value `20-77542145` is not a valid telephone number
The Telephone4 value `775421451` is not a valid telephone number
Example (Url)
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		URL1 string `v:"url"`
		URL2 string `v:"url"`
		URL3 string `v:"url"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			URL1: "http://goframe.org",
			URL2: "ftp://goframe.org",
			URL3: "ws://goframe.org",
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The URL3 value `ws://goframe.org` is not a valid URL address

func New

func New() *Validator

New creates and returns a new Validator.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

}
Output:

The value `16` must be equal or greater than 18

func (*Validator) Assoc

func (v *Validator) Assoc(assoc any) *Validator

Assoc is a chaining operation function, which sets associated validation data for current operation. The optional parameter `assoc` is usually type of map, which specifies the parameter map used in union validation. Calling this function with `assoc` also sets `useAssocInsteadOfObjectAttributes` true

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
)

func main() {
	type User struct {
		Name string `v:"required"`
		Type int    `v:"required"`
	}
	data := g.Map{
		"name": "john",
	}
	user := User{}

	if err := gconv.Scan(data, &user); err != nil {
		panic(err)
	}

	if err := g.Validator().Data(user).Assoc(data).Run(context.Background()); err != nil {
		fmt.Print(err)
	}

}
Output:

The Type field is required

func (*Validator) Bail

func (v *Validator) Bail() *Validator

Bail sets the mark for stopping validation after the first validation error.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Account   string `v:"required|length:6,16|same:QQ"`
		QQ        string
		Password  string `v:"required|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Account:   "gf",
			QQ:        "123456",
			Password:  "goframe.org",
			Password2: "goframe.org",
		}
	)

	if err := g.Validator().Bail().Data(req).Run(ctx); err != nil {
		fmt.Println("Use Bail Error:", err)
	}

	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println("Not Use Bail Error:", err)
	}

}
Output:

Use Bail Error: The Account value `gf` length must be between 6 and 16
Not Use Bail Error: The Account value `gf` length must be between 6 and 16; The Account value `gf` must be the same as field QQ value `123456`

func (*Validator) Ci

func (v *Validator) Ci() *Validator

Ci sets the mark for Case-Insensitive for those rules that need value comparison.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Account   string `v:"required"`
		Password  string `v:"required|same:Password2"`
		Password2 string `v:"required"`
	}
	var (
		ctx = context.Background()
		req = BizReq{
			Account:   "gf",
			Password:  "Goframe.org", // Diff from Password2, but because of "ci", rule check passed
			Password2: "goframe.org",
		}
	)

	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Println("Not Use CI Error:", err)
	}

	if err := g.Validator().Ci().Data(req).Run(ctx); err == nil {
		fmt.Println("Use CI Passed!")
	}

}
Output:

Not Use CI Error: The Password value `Goframe.org` must be the same as field Password2 value `goframe.org`
Use CI Passed!

func (*Validator) Clone

func (v *Validator) Clone() *Validator

Clone creates and returns a new Validator, which is a shallow copy of the current one.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

	if err := g.Validator().Clone().Data(20).Run(context.Background()); err != nil {
		fmt.Println(err)
	} else {
		fmt.Println("Check Success!")
	}

}
Output:

The value `16` must be equal or greater than 18
Check Success!

func (*Validator) Data

func (v *Validator) Data(data any) *Validator

Data is a chaining operation function, which sets validation data for current operation.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	type BizReq struct {
		Password1 string `v:"password"`
		Password2 string `v:"password"`
	}

	var (
		ctx = context.Background()
		req = BizReq{
			Password1: "goframe",
			Password2: "gofra", // error length between 6 and 18
		}
	)
	if err := g.Validator().Data(req).Run(ctx); err != nil {
		fmt.Print(err)
	}

}
Output:

The Password2 value `gofra` is not a valid password format
Example (Map1)
package main

import (
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	params := map[string]any{
		"passport":  "",
		"password":  "123456",
		"password2": "1234567",
	}
	rules := []string{
		"passport@required|length:6,16#账号不能为空|账号长度应当在{min}到{max}之间",
		"password@required|length:6,16|same{password}2#密码不能为空|密码长度应当在{min}到{max}之间|两次密码输入不相等",
		"password2@required|length:6,16#",
	}
	if e := g.Validator().Data(params).Rules(rules).Run(gctx.New()); e != nil {
		fmt.Println(e.Map())
		fmt.Println(e.FirstItem())
		fmt.Println(e.FirstError())
	}
	// May Output:
	// map[required:The passport field is required length:The passport value `` length must be between 6 and 16]
	// passport map[required:The passport field is required length:The passport value `` length must be between 6 and 16]
	// The passport field is required
}
Example (Map2)
package main

import (
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	params := map[string]any{
		"passport":  "",
		"password":  "123456",
		"password2": "1234567",
	}
	rules := []string{
		"passport@length:6,16#账号不能为空|账号长度应当在{min}到{max}之间",
		"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在{min}到{max}之间|两次密码输入不相等",
		"password2@required|length:6,16#",
	}
	if e := g.Validator().Data(params).Rules(rules).Run(gctx.New()); e != nil {
		fmt.Println(e.Map())
		fmt.Println(e.FirstItem())
		fmt.Println(e.FirstError())
	}
}
Output:

map[same:两次密码输入不相等]
password map[same:两次密码输入不相等]
两次密码输入不相等
Example (Map3)
package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	params := map[string]any{
		"passport":  "",
		"password":  "123456",
		"password2": "1234567",
	}
	rules := map[string]string{
		"passport":  "required|length:6,16",
		"password":  "required|length:6,16|same:password2",
		"password2": "required|length:6,16",
	}
	messages := map[string]any{
		"passport": "账号不能为空|账号长度应当在{min}到{max}之间",
		"password": map[string]string{
			"required": "密码不能为空",
			"same":     "两次密码输入不相等",
		},
	}
	err := g.Validator().
		Messages(messages).
		Rules(rules).
		Data(params).Run(gctx.New())
	if err != nil {
		g.Dump(err.Maps())
	}

	// May Output:
	// {
	//	"passport": {
	//	"length": "The passport value `` length must be between 6 and 16",
	//		"required": "The passport field is required"
	// },
	//	"password": {
	//	"same": "The password value `123456` must be the same as field password2 value `1234567`"
	// }
	// }
}
Example (Struct1)

Empty string attribute.

package main

import (
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	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 := g.Validator().Data(obj).Run(gctx.New())
	fmt.Println(err == nil)
}
Output:

true
Example (Struct2)

Empty pointer attribute.

package main

import (
	"fmt"

	"github.com/gogf/gf/v2/container/gvar"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	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 := g.Validator().Data(obj).Run(gctx.New())
	fmt.Println(err == nil)
}
Output:

true
Example (Struct3)

Empty integer attribute.

package main

import (
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	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 := g.Validator().Data(obj).Run(gctx.New())
	fmt.Println(err)
}
Output:

project id must between 1, 10000
Example (Struct4)
package main

import (
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gconv"
)

func main() {
	type User struct {
		Name string `v:"required#请输入用户姓名"`
		Type int    `v:"required#请选择用户类型"`
	}
	data := g.Map{
		"name": "john",
	}
	user := User{}
	if err := gconv.Scan(data, &user); err != nil {
		panic(err)
	}
	err := g.Validator().Data(user).Assoc(data).Run(gctx.New())
	if err != nil {
		fmt.Println(err.Items())
	}

}
Output:

[map[Type:map[required:请选择用户类型]]]
Example (Value)
package main

import (
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

func main() {
	err := g.Validator().Rules("min:18").
		Messages("未成年人不允许注册哟").
		Data(16).Run(gctx.New())
	fmt.Println(err.String())

}
Output:

未成年人不允许注册哟

func (*Validator) Foreach added in v2.2.0

func (v *Validator) Foreach() *Validator

Foreach tells the next validation using current value as an array and validates each of its element. Note that this decorating rule takes effect just once for next validation rule, specially for single value validation.

func (*Validator) I18n

func (v *Validator) I18n(i18nManager *gi18n.Manager) *Validator

I18n sets the i18n manager for the validator.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/i18n/gi18n"
	"github.com/gogf/gf/v2/test/gtest"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	var (
		i18nManager = gi18n.New(gi18n.Options{Path: gtest.DataPath("i18n")})
		ctxCn       = gi18n.WithLanguage(context.Background(), "cn")
		validator   = gvalid.New()
	)

	validator = validator.Data(16).Rules("min:18")

	if err := validator.Run(context.Background()); err != nil {
		fmt.Println(err)
	}

	if err := validator.I18n(i18nManager).Run(ctxCn); err != nil {
		fmt.Println(err)
	}

}
Output:

The value `16` must be equal or greater than 18
字段值`16`字段最小值应当为18

func (*Validator) Messages

func (v *Validator) Messages(messages any) *Validator

Messages is a chaining operation function, which sets custom error messages for current operation. The parameter `messages` can be type of string/[]string/map[string]string. It supports sequence in error result if `rules` is type of []string.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Messages("Can not regist, Age is less then 18!").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

}
Output:

Can not regist, Age is less then 18!

func (*Validator) RuleFunc

func (v *Validator) RuleFunc(rule string, f RuleFunc) *Validator

RuleFunc registers one custom rule function to current Validator.

Example
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	var (
		ctx             = context.Background()
		lenErrRuleName  = "LenErr"
		passErrRuleName = "PassErr"
		lenErrRuleFunc  = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if len(pass) != 6 {
				return errors.New(in.Message)
			}
			return nil
		}
		passErrRuleFunc = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if m := in.Data.Map(); m["data"] != pass {
				return errors.New(in.Message)
			}
			return nil
		}
	)

	type LenErrStruct struct {
		Value string `v:"uid@LenErr#Value Length Error!"`
		Data  string `p:"data"`
	}

	st := &LenErrStruct{
		Value: "123",
		Data:  "123456",
	}
	// single error sample
	if err := g.Validator().RuleFunc(lenErrRuleName, lenErrRuleFunc).Data(st).Run(ctx); err != nil {
		fmt.Println(err)
	}

	type MultiErrorStruct struct {
		Value string `v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!"`
		Data  string `p:"data"`
	}

	multi := &MultiErrorStruct{
		Value: "123",
		Data:  "123456",
	}
	// multi error sample
	if err := g.Validator().RuleFunc(lenErrRuleName, lenErrRuleFunc).RuleFunc(passErrRuleName, passErrRuleFunc).Data(multi).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

Value Length Error!
Value Length Error!; Pass is not Same!

func (*Validator) RuleFuncMap

func (v *Validator) RuleFuncMap(m map[string]RuleFunc) *Validator

RuleFuncMap registers multiple custom rule functions to current Validator.

Example
package main

import (
	"context"
	"errors"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gvalid"
)

func main() {
	var (
		ctx             = context.Background()
		lenErrRuleName  = "LenErr"
		passErrRuleName = "PassErr"
		lenErrRuleFunc  = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if len(pass) != 6 {
				return errors.New(in.Message)
			}
			return nil
		}
		passErrRuleFunc = func(ctx context.Context, in gvalid.RuleFuncInput) error {
			pass := in.Value.String()
			if m := in.Data.Map(); m["data"] != pass {
				return errors.New(in.Message)
			}
			return nil
		}
		ruleMap = map[string]gvalid.RuleFunc{
			lenErrRuleName:  lenErrRuleFunc,
			passErrRuleName: passErrRuleFunc,
		}
	)

	type MultiErrorStruct struct {
		Value string `v:"uid@LenErr|PassErr#Value Length Error!|Pass is not Same!"`
		Data  string `p:"data"`
	}

	multi := &MultiErrorStruct{
		Value: "123",
		Data:  "123456",
	}

	if err := g.Validator().RuleFuncMap(ruleMap).Data(multi).Run(ctx); err != nil {
		fmt.Println(err)
	}

}
Output:

Value Length Error!; Pass is not Same!

func (*Validator) Rules

func (v *Validator) Rules(rules any) *Validator

Rules is a chaining operation function, which sets custom validation rules for current operation.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println(err)
	}

}
Output:

The value `16` must be equal or greater than 18

func (*Validator) Run

func (v *Validator) Run(ctx context.Context) Error

Run starts validating the given data with rules and messages.

Example
package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
)

func main() {
	// check value mode
	if err := g.Validator().Data(16).Rules("min:18").Run(context.Background()); err != nil {
		fmt.Println("check value err:", err)
	}
	// check map mode
	data := map[string]any{
		"passport":  "",
		"password":  "123456",
		"password2": "1234567",
	}
	rules := map[string]string{
		"passport":  "required|length:6,16",
		"password":  "required|length:6,16|same:password2",
		"password2": "required|length:6,16",
	}
	if err := g.Validator().Data(data).Rules(rules).Run(context.Background()); err != nil {
		fmt.Println("check map err:", err)
	}
	// check struct mode
	type Params struct {
		Page      int    `v:"required|min:1"`
		Size      int    `v:"required|between:1,100"`
		ProjectId string `v:"between:1,10000"`
	}
	rules = map[string]string{
		"Page":      "required|min:1",
		"Size":      "required|between:1,100",
		"ProjectId": "between:1,10000",
	}
	obj := &Params{
		Page: 0,
		Size: 101,
	}
	if err := g.Validator().Data(obj).Run(context.Background()); err != nil {
		fmt.Println("check struct err:", err)
	}

	// May Output:
	// check value err: The value `16` must be equal or greater than 18
	// check map err: The passport field is required; The passport value `` length must be between 6 and 16; The password value `123456` must be the same as field password2
	// check struct err: The Page value `0` must be equal or greater than 1; The Size value `101` must be between 1 and 100
}

Directories

Path Synopsis
internal
builtin
Package builtin implements built-in validation rules.
Package builtin implements built-in validation rules.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL