日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
創(chuàng)新互聯(lián)GoFrame教程:GoFrame自定義規(guī)則-規(guī)則注冊

雖然?gvalid?已經內置了常見的數(shù)十種校驗規(guī)則,但是在部分業(yè)務場景下我們需要自定義校驗規(guī)則,特別是一些可以重復使用的業(yè)務相關的校驗規(guī)則。當然,?gvalid?如此的強大和貼心,她已經為您考慮得如此周全。自定義校驗規(guī)則可以實現(xiàn)靈活性強,可復用性高的校驗特性。

創(chuàng)新互聯(lián)建站-專業(yè)網站定制、快速模板網站建設、高性價比黎平網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式黎平網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋黎平地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。

相關數(shù)據(jù)結構

自定義規(guī)則方法定義,以及對應的輸入?yún)?shù)數(shù)據(jù)結構。

// RuleFuncInput holds the input parameters that passed to custom rule function RuleFunc.
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

	// 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
}

// RuleFunc is the custom function for data validation.
type RuleFunc func(ctx context.Context, in RuleFuncInput) error

方法參數(shù)簡要說明:

  1. 上下文參數(shù)?ctx?是必須的。
  2. ?RuleFuncInput?數(shù)據(jù)結構說明:
    • ?Rule?表示當前的校驗規(guī)則,包含規(guī)則的參數(shù),例如:?required?,  ?between:1,100?,  ?length:6?等等。
    • ?Message?參數(shù)表示在校驗失敗后返回的校驗錯誤提示信息。
    • ?Value?參數(shù)表示被校驗的數(shù)據(jù)值,注意類型是一個?*gvar.Var?泛型,因此您可以傳遞任意類型的參數(shù)。
    • ?Data?參數(shù)表示校驗時傳遞的參數(shù),例如校驗的是一個?map?或者?struct?時,往往在聯(lián)合校驗時有用。需要注意的是,這個值是運行時輸入的,值可能是?nil?。

自定義錯誤默認情況下已支持?i18n?特性,因此您只需要按照 ?gf.gvalid.rule.自定義規(guī)則名稱? 配置?i18n?轉譯信息即可,該信息在校驗失敗時會自動從?i18n?管理器獲取后,通過?Message?參數(shù)傳入給您注冊的自定義校驗方法中。

全局校驗規(guī)則注冊

自定義規(guī)則分為兩種:全局規(guī)則注冊和局部規(guī)則注冊。

全局規(guī)則是全局生效的規(guī)則,注冊之后無論是使用方法還是對象來執(zhí)行數(shù)據(jù)校驗都可以使用自定義的規(guī)則。

注冊校驗方法:

// RegisterRule registers custom validation rule and function for package.
func RegisterRule(rule string, f RuleFunc) {
	customRuleFuncMap[rule] = f
}

// RegisterRuleByMap registers custom validation rules using map for package.
func RegisterRuleByMap(m map[string]RuleFunc) {
	for k, v := range m {
		customRuleFuncMap[k] = v
	}
}

您需要按照?RuleFunc?類型的方法定義,實現(xiàn)一個您需要的校驗方法,隨后使用?RegisterRule?注冊到?gvalid?模塊中全局管理。該注冊邏輯往往是在程序初始化時執(zhí)行。該方法在對數(shù)據(jù)進行校驗時將會被自動調用,方法返回?nil?表示校驗通過,否則應當返回一個非空的?error?類型值。

注意事項:自定義規(guī)則的注冊方法不支持并發(fā)調用,您需要在程序啟動時進行注冊(例如在?boot?包中處理),無法在運行時動態(tài)注冊,否則會產生并發(fā)安全問題。

示例1,訂單ID存在校驗

在電商業(yè)務中,當我們對訂單進行操作時,可以通過自定義規(guī)則校驗給定的訂單?ID?是否存在,因此我們可以注冊一個?order-exist?的全局規(guī)則來實現(xiàn)。

package main

import (
	"context"
	"fmt"
	"github.com/GOgf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gvalid"
	"time"
)

type Request struct {
	OrderId     int64
	ProductName string
	Amount      int64
	// ...
}

func init() {
	rule := "order-exist"
	gvalid.RegisterRule(rule, RuleOrderExist)
}

func RuleOrderExist(ctx context.Context, in gvalid.RuleFuncInput) error {
	// SELECT COUNT(*) FROM `order` WHERE `id` = xxx
	count, err := g.Model("order").
		Ctx(ctx).
		Cache(gdb.CacheOption{
			Duration: time.Hour,
			Name:     "",
			Force:    false,
		}).
		WhereNot("id", in.Value.Int64()).
		Count()
	if err != nil {
		return err
	}
	if count == 0 {
		return gerror.Newf(`invalid order id "%d"`, in.Value.Int64())
	}
	return nil
}

func main() {
	var (
		ctx = gctx.New()
		req = &Request{
			OrderId:     65535,
			ProductName: "HikingShoe",
			Amount:      10000,
		}
	)
	err := g.Validator().CheckStruct(ctx, req)
	fmt.Println(err)
}

示例2,用戶唯一性規(guī)則

在用戶注冊時,我們往往需要校驗當前用戶提交的名稱/賬號是否唯一,因此我們可以注冊一個??unique-nam?e?的全局規(guī)則來實現(xiàn)。

package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gvalid"
	"time"
)

type User struct {
	Id   int
	Name string `v:"required|unique-name#請輸入用戶名稱|用戶名稱已被占用"`
	Pass string `v:"required|length:6,18"`
}

func init() {
	rule := "unique-name"
	gvalid.RegisterRule(rule, RuleUniqueName)
}

func RuleUniqueName(ctx context.Context, in gvalid.RuleFuncInput) error {
	var user *User
	if err := in.Data.Scan(&user); err != nil {
		return gerror.Wrap(err, `Scan data to user failed`)
	}
	// SELECT COUNT(*) FROM `user` WHERE `id` != xxx AND `name` != xxx
	count, err := g.Model("user").
		Ctx(ctx).
		Cache(gdb.CacheOption{
			Duration: time.Hour,
			Name:     "",
			Force:    false,
		}).
		WhereNot("id", user.Id).
		WhereNot("name", user.Name).
		Count()
	if err != nil {
		return err
	}
	if count > 0 {
		if in.Message != "" {
			return gerror.New(in.Message)
		}
		return gerror.Newf(`user name "%s" is already token by others`, user.Name)
	}
	return nil
}

func main() {
	var (
		ctx  = gctx.New()
		user = &User{
			Id:   1,
			Name: "john",
			Pass: "123456",
		}
	)
	err := g.Validator().CheckStruct(ctx, user)
	fmt.Println(err)
}

局部校驗規(guī)則注冊

局部規(guī)則是僅在當前校驗對象下生效規(guī)則,校驗規(guī)則是注冊到當前使用的鏈式操作流程中而不是全局中。

注冊方法:

// RuleFunc registers one custom rule function to current Validator.
func (v *Validator) RuleFunc(rule string, f RuleFunc) *Validator

// RuleFuncMap registers multiple custom rule functions to current Validator.
func (v *Validator) RuleFuncMap(m map[string]RuleFunc) *Validator

簡要介紹:

  • ?RuleFunc?方法用于注冊單個自定義校驗規(guī)則到當前對象。
  • ?RuleFuncMap?方法用于注冊多個自定義校驗規(guī)則到當前對象。

使用示例:

我們將上面其中一個例子改為局部校驗規(guī)則注冊。

package main

import (
	"context"
	"fmt"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gvalid"
	"time"
)

type Request struct {
	OrderId     int64
	ProductName string
	Amount      int64
	// ...
}

func RuleOrderExist(ctx context.Context, in gvalid.RuleFuncInput) error {
	// SELECT COUNT(*) FROM `order` WHERE `id` = xxx
	count, err := g.Model("order").
		Ctx(ctx).
		Cache(gdb.CacheOption{
			Duration: time.Hour,
			Name:     "",
			Force:    false,
		}).
		WhereNot("id", in.Value.Int64()).
		Count()
	if err != nil {
		return err
	}
	if count == 0 {
		return gerror.Newf(`invalid order id "%d"`, in.Value.Int64())
	}
	return nil
}

func main() {
	var (
		ctx = gctx.New()
		req = &Request{
			OrderId:     65535,
			ProductName: "HikingShoe",
			Amount:      10000,
		}
	)
	err := g.Validator().RuleFunc("order-exist", RuleOrderExist).Data(req).Run(ctx)  
	fmt.Println(err)
}

文章標題:創(chuàng)新互聯(lián)GoFrame教程:GoFrame自定義規(guī)則-規(guī)則注冊
本文URL:http://www.dlmjj.cn/article/cdjhesp.html