Golang?PHP?數(shù)據(jù)綁定示例分析
強(qiáng)類型語言
數(shù)據(jù)綁定
在強(qiáng)類型語言中,綁定參數(shù)分好幾種類型。拿最使用廣泛的Gin web 框架介紹
1、Bind 和 ShouldBind
Gin 的 Context 為請求數(shù)據(jù)綁定提供了兩大類方法:在命名上以 Bind 為前綴和以 ShouldBind區(qū)分。這兩大類方法在行為上有些差異。
類型 | 描述 |
---|---|
must | 條件必須要滿足 |
should | 條件應(yīng)該滿足 |
Bind
方法會自動將 http status
設(shè)置為 400。而且不會返回更多的信息。由于存在,錯誤處理復(fù)雜,限制較多(僅僅支持常見類型),驗(yàn)證規(guī)則限制簡單,可能存在安全風(fēng)險等等在日常開發(fā)中幾乎不建議使用bind 來綁定數(shù)據(jù)
ShouldBind、ShouldBindJSON 這些方法的區(qū)別是前者會自動根據(jù) Header 頭確定使用什么綁定器,如果團(tuán)隊(duì)內(nèi)開發(fā)規(guī)范里約定了請求 Content-Type 都是 JSON 的話,直接選用后者更為合理。
在實(shí)際開發(fā)中,ShouldBind 自動根據(jù)Header 頭確定使用什么綁定器使用最多。因?yàn)閳F(tuán)隊(duì)的約定對新加入的團(tuán)隊(duì)的人來說沒看到約定的情況下,容易出現(xià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 的話,對于強(qiáng)類型語言來說,使用下面這段更合理,一般情況還是用上面這種。 if err := ctx.ShouldBindJson(&request); err != nil { core.Response(ctx, gin.H{}, err) return }
2、單次綁定和多次綁定request body 數(shù)據(jù)
有了上面的綁定基礎(chǔ)情況下,小編遇到了這樣的一個問題。權(quán)限驗(yàn)證
中間件,在接收參數(shù)的時候使用的下面代碼的接收參數(shù)的方式。接口的請求參數(shù)是Content-Type 都是 JSON 的類型的。
message := ctx.PostForm("message") ids := ctx.QueryMap("ids") message := ctx.GetQuery("message")
此時此刻,為了讓接口綁定參數(shù)和中間件綁定參數(shù),就會有二次綁定的數(shù)據(jù)的問題。小編楞是找了半天,原來強(qiáng)類型語言,幾乎對類型都有做區(qū)分。不管是json get post request 類型每種類型都做了區(qū)分,連二次綁定都做了區(qū)分,不得不說,為了性能犧牲編寫代碼的體驗(yàn)。所以關(guān)鍵來了
無論是 Bind 還是 ShouldBind 類的綁定方法,都只能讀取一次請求體進(jìn)行綁定
可以使用ShouldBindBodyWith
來實(shí)現(xiàn)二次及多次綁定。那問題又來了,使用了ShouldBindBodyWith
綁定從一個參數(shù)被綁定開始,后面的綁定都得使用ShouldBindBodyWith
來綁定,有這樣的限制才能實(shí)現(xiàn)多次綁定
if err := ctx.ShouldBindBodyWith(&request,binding.JSON); err != nil { core.Response(ctx, gin.H{}, err) return }
到了這里基本上對參數(shù)綁定有了一定的了解。不同類型需要相互轉(zhuǎn)換,不同的的場景需要不同的方法來實(shí)現(xiàn)。相對于弱類型語言PHP
來說,不管三七二一,一鍵全部接收,不管什么類型,一次綁定還是多次綁定也好,照單全收,這樣的處理也間接導(dǎo)致弱類型語言在底層處理上需要兼容各種類型,性能也相對于強(qiáng)類型語言編譯需要更多的內(nèi)容空間和消耗更多的CPU資源。
3、通用類型綁定
在強(qiáng)類型語言中,接收參數(shù)的時候,常用結(jié)構(gòu)體來綁定數(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"` }
那么問題來了,要接收數(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"` }
那么問題又來了,這種類型是json 格式固定的情況下,那么需求有變動,就得更新代碼新增結(jié)構(gòu)體字段。增加一個結(jié)構(gòu)體字段,就得重新編譯一次。那沒有接收通用類型的字段值。
接下來 interface
類型就派上用場了。interface
類型為通用類型,MySQL
數(shù)據(jù)庫沒有這種類型。還需要將interface
類型轉(zhuǎn)成 json,string,int 這樣的類型才能保存。所以在接收通用數(shù)據(jù)參數(shù)格式的時候,得借助MySQL第三方擴(kuò)展庫在標(biāo)識,接收通用類型是 text string 還是json 類型
type UserGroupTask struct { Test1 interface{} `json:"test1" form:"test1" gorm:"type:'json'"` }
通過標(biāo)識 gorm
標(biāo)識,interface
類型為json
。這樣在shouldBindJSON
的時候,才能識別出是JSON 格式。
總結(jié)
上面介紹了強(qiáng)類型語言,需要對字段類型做轉(zhuǎn)化、數(shù)據(jù)綁定類型指定等,在弱類型語言中在底層封裝好了。
留下一個疑問,上面的代碼接收通用格式,怎么在盡可能少寫結(jié)果體的前提下,把json 格式的參數(shù)取出來做判斷后,在入到數(shù)據(jù)庫里去呢。
更多關(guān)于Golang PHP 數(shù)據(jù)綁定的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
使用golang進(jìn)行http,get或postJson請求
這篇文章主要為大家詳細(xì)介紹了如何使用golang進(jìn)行http,get或postJson請求,文中的示例代碼簡潔易懂,具有一定的借鑒價值,感興趣的小伙伴可以了解一下2023-12-12Go語言中Redis緩存與本地內(nèi)存緩存實(shí)戰(zhàn)
在現(xiàn)代高并發(fā)系統(tǒng)中,緩存技術(shù)是提升性能和降低數(shù)據(jù)庫壓力的關(guān)鍵手段,本文將為大家介紹一下Redis緩存與本地內(nèi)存緩存的具體應(yīng)用,需要的可以了解下2025-03-03Go語言并發(fā)之Sync包的6個關(guān)鍵概念總結(jié)
這篇文章主要為大家詳細(xì)介紹了Go語言并發(fā)中Sync包的6個關(guān)鍵概念,文中的示例代碼講解詳細(xì),對我們深入學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下2023-05-05Go設(shè)計(jì)模式原型模式考查點(diǎn)及使用詳解
這篇文章主要為大家介紹了Go設(shè)計(jì)模式原型模式考查點(diǎn)及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12詳解Go語言Sync.Pool為何不加鎖也能夠?qū)崿F(xiàn)線程安全
在這篇文章中,我們將剖析sync.Pool內(nèi)部實(shí)現(xiàn)中,介紹了sync.Pool比較巧妙的內(nèi)部設(shè)計(jì)思路以及其實(shí)現(xiàn)方式。在這個過程中,也間接介紹了為何不加鎖也能夠?qū)崿F(xiàn)線程安全,感興趣的可以學(xué)習(xí)一下2023-04-04Go?CSV包實(shí)現(xiàn)結(jié)構(gòu)體和csv內(nèi)容互轉(zhuǎn)工具詳解
這篇文章主要介紹了Go?CSV包實(shí)現(xiàn)結(jié)構(gòu)體和csv內(nèi)容互轉(zhuǎn)工具詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03