Golang?PHP?數(shù)據(jù)綁定示例分析
強(qiáng)類型語(yǔ)言
數(shù)據(jù)綁定
在強(qiáng)類型語(yǔ)言中,綁定參數(shù)分好幾種類型。拿最使用廣泛的Gin web 框架介紹
1、Bind 和 ShouldBind
Gin 的 Context 為請(qǐng)求數(shù)據(jù)綁定提供了兩大類方法:在命名上以 Bind 為前綴和以 ShouldBind區(qū)分。這兩大類方法在行為上有些差異。
| 類型 | 描述 |
|---|---|
| must | 條件必須要滿足 |
| should | 條件應(yīng)該滿足 |
Bind 方法會(huì)自動(dòng)將 http status 設(shè)置為 400。而且不會(huì)返回更多的信息。由于存在,錯(cuò)誤處理復(fù)雜,限制較多(僅僅支持常見類型),驗(yàn)證規(guī)則限制簡(jiǎn)單,可能存在安全風(fēng)險(xiǎn)等等在日常開發(fā)中幾乎不建議使用bind 來(lái)綁定數(shù)據(jù)
ShouldBind、ShouldBindJSON 這些方法的區(qū)別是前者會(huì)自動(dòng)根據(jù) Header 頭確定使用什么綁定器,如果團(tuán)隊(duì)內(nèi)開發(fā)規(guī)范里約定了請(qǐng)求 Content-Type 都是 JSON 的話,直接選用后者更為合理。
在實(shí)際開發(fā)中,ShouldBind 自動(dòng)根據(jù)Header 頭確定使用什么綁定器使用最多。因?yàn)閳F(tuán)隊(duì)的約定對(duì)新加入的團(tuán)隊(duì)的人來(lái)說(shuō)沒(méi)看到約定的情況下,容易出現(xiàn)代碼不兼容的問(wèn)題。
var request struct {
Email string `form:"email" binding:"required"`
Name string `form:"name" binding:"required"`
}
// ShouldBind 常規(guī)綁定也可以兼容post get json 參數(shù)
if err := ctx.ShouldBind(&request); err != nil {
core.Response(ctx, gin.H{}, err)
return
}
// Content-Type 都是 JSON 的話,對(duì)于強(qiáng)類型語(yǔ)言來(lái)說(shuō),使用下面這段更合理,一般情況還是用上面這種。
if err := ctx.ShouldBindJson(&request); err != nil {
core.Response(ctx, gin.H{}, err)
return
}2、單次綁定和多次綁定request body 數(shù)據(jù)
有了上面的綁定基礎(chǔ)情況下,小編遇到了這樣的一個(gè)問(wèn)題。權(quán)限驗(yàn)證中間件,在接收參數(shù)的時(shí)候使用的下面代碼的接收參數(shù)的方式。接口的請(qǐng)求參數(shù)是Content-Type 都是 JSON 的類型的。
message := ctx.PostForm("message")
ids := ctx.QueryMap("ids")
message := ctx.GetQuery("message")此時(shí)此刻,為了讓接口綁定參數(shù)和中間件綁定參數(shù),就會(huì)有二次綁定的數(shù)據(jù)的問(wèn)題。小編楞是找了半天,原來(lái)強(qiáng)類型語(yǔ)言,幾乎對(duì)類型都有做區(qū)分。不管是json get post request 類型每種類型都做了區(qū)分,連二次綁定都做了區(qū)分,不得不說(shuō),為了性能犧牲編寫代碼的體驗(yàn)。所以關(guān)鍵來(lái)了
無(wú)論是 Bind 還是 ShouldBind 類的綁定方法,都只能讀取一次請(qǐng)求體進(jìn)行綁定
可以使用ShouldBindBodyWith 來(lái)實(shí)現(xiàn)二次及多次綁定。那問(wèn)題又來(lái)了,使用了ShouldBindBodyWith 綁定從一個(gè)參數(shù)被綁定開始,后面的綁定都得使用ShouldBindBodyWith 來(lái)綁定,有這樣的限制才能實(shí)現(xiàn)多次綁定
if err := ctx.ShouldBindBodyWith(&request,binding.JSON); err != nil {
core.Response(ctx, gin.H{}, err)
return
}到了這里基本上對(duì)參數(shù)綁定有了一定的了解。不同類型需要相互轉(zhuǎn)換,不同的的場(chǎng)景需要不同的方法來(lái)實(shí)現(xiàn)。相對(duì)于弱類型語(yǔ)言PHP來(lái)說(shuō),不管三七二一,一鍵全部接收,不管什么類型,一次綁定還是多次綁定也好,照單全收,這樣的處理也間接導(dǎo)致弱類型語(yǔ)言在底層處理上需要兼容各種類型,性能也相對(duì)于強(qiáng)類型語(yǔ)言編譯需要更多的內(nèi)容空間和消耗更多的CPU資源。
3、通用類型綁定
在強(qiáng)類型語(yǔ)言中,接收參數(shù)的時(shí)候,常用結(jié)構(gòu)體來(lái)綁定數(shù)據(jù)類型。每種結(jié)構(gòu)體定義一種類型。而且首字母要大寫。
type request struct {
Email string `form:"email" binding:"required"`
Name string `form:"name" binding:"required"`
Age int `form:"age" binding:"required"`
}那么問(wèn)題來(lái)了,要接收數(shù)據(jù)格式為json 數(shù)據(jù)格式怎么辦。貌似單一的數(shù)據(jù)string int 等數(shù)據(jù)格式都不能滿足了,需要嵌套結(jié)構(gòu)體如下:
type Grouping struct {
ID int `json:"id"`
Remark string `json:"remark" default:""`
}
type Group struct {
Test1 []*Grouping `json:"test1"`
Test2 Grouping `json:"test2"`
Test3 string `json:"test3"`
Test4 int `json:"test4"`
}那么問(wèn)題又來(lái)了,這種類型是json 格式固定的情況下,那么需求有變動(dòng),就得更新代碼新增結(jié)構(gòu)體字段。增加一個(gè)結(jié)構(gòu)體字段,就得重新編譯一次。那沒(méi)有接收通用類型的字段值。
接下來(lái) interface 類型就派上用場(chǎng)了。interface 類型為通用類型,MySQL 數(shù)據(jù)庫(kù)沒(méi)有這種類型。還需要將interface 類型轉(zhuǎn)成 json,string,int 這樣的類型才能保存。所以在接收通用數(shù)據(jù)參數(shù)格式的時(shí)候,得借助MySQL第三方擴(kuò)展庫(kù)在標(biāo)識(shí),接收通用類型是 text string 還是json 類型
type UserGroupTask struct {
Test1 interface{} `json:"test1" form:"test1" gorm:"type:'json'"`
}通過(guò)標(biāo)識(shí) gorm 標(biāo)識(shí),interface 類型為json。這樣在shouldBindJSON 的時(shí)候,才能識(shí)別出是JSON 格式。
總結(jié)
上面介紹了強(qiáng)類型語(yǔ)言,需要對(duì)字段類型做轉(zhuǎn)化、數(shù)據(jù)綁定類型指定等,在弱類型語(yǔ)言中在底層封裝好了。
留下一個(gè)疑問(wèn),上面的代碼接收通用格式,怎么在盡可能少寫結(jié)果體的前提下,把json 格式的參數(shù)取出來(lái)做判斷后,在入到數(shù)據(jù)庫(kù)里去呢。
更多關(guān)于Golang PHP 數(shù)據(jù)綁定的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于Go語(yǔ)言實(shí)現(xiàn)高性能文件上傳下載系統(tǒng)
在Web應(yīng)用開發(fā)中,文件上傳下載是一個(gè)非常常見的需求,本文將介紹如何使用Go語(yǔ)言實(shí)現(xiàn)一個(gè)安全、高效的本地文件存儲(chǔ)系統(tǒng),感興趣的小伙伴可以了解下2025-03-03
Go中的函數(shù)選項(xiàng)模式(Functional Options Pattern)詳解
在 Go 語(yǔ)言中,函數(shù)選項(xiàng)模式是一種優(yōu)雅的設(shè)計(jì)模式,用于處理函數(shù)的可選參數(shù),本文將對(duì)其進(jìn)行講解,準(zhǔn)備好了嗎,快跟隨著本文一探究竟吧2023-06-06
golang的強(qiáng)制類型轉(zhuǎn)換實(shí)現(xiàn)
這篇文章主要介紹了golang的強(qiáng)制類型轉(zhuǎn)換實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
Go語(yǔ)言實(shí)現(xiàn)Sm2加解密的示例代碼
本文主要介紹了Go語(yǔ)言實(shí)現(xiàn)Sm2加解密的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
Go接口構(gòu)建可擴(kuò)展Go應(yīng)用示例詳解
本文深入探討了Go語(yǔ)言中接口的概念和實(shí)際應(yīng)用場(chǎng)景。從基礎(chǔ)知識(shí)如接口的定義和實(shí)現(xiàn),到更復(fù)雜的實(shí)戰(zhàn)應(yīng)用如解耦與抽象、多態(tài)、錯(cuò)誤處理、插件架構(gòu)以及資源管理,文章通過(guò)豐富的代碼示例和詳細(xì)的解釋,展示了Go接口在軟件開發(fā)中的強(qiáng)大功能和靈活性2023-10-10

