本章节的复杂参数针对于传统的Query或者Form参数传递,由于这两种参数传递方式对复杂参数传递的管理维护不是很优雅,因为我们推荐大家遇到复杂参数传递的场景尽量使用JSON数据编码来管理维护。

复杂参数

ghttp.Request对象支持智能的参数类型解析(不区分请求提交方式及请求提交类型),以下为提交参数示例以及服务端对应解析的变量类型:

ParameterVariable
k=m&k=nmap[k:n]
k1=m&k2=nmap[k1:m k2:n]
k[]=m&k[]=nmap[k:[m n]]
k[a][]=m&k[a][]=nmap[k:map[a:[m n]]]
k[a]=m&k[b]=nmap[k:map[a:m b:n]]
k[a][a]=m&k[a][b]=nmap[k:map[a:map[a:m b:n]]]
k=m&k[a]=nerror

同名参数

同名参数提交格式形如:k=v1&k=v2 ,后续的变量值将会覆盖前面的变量值。

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

func main() {
	s := g.Server()
	s.BindHandler("/", func(r *ghttp.Request) {
		r.Response.Write(r.Get("name"))
	})
	s.SetPort(8199)
	s.Run()
}

执行后,我们访问 http://127.0.0.1:8199/?name=john&name=smith 后,将会得到返回值 smith

注意:框架的HTTP Server在这块的处理逻辑参考PHP,会和Go标准库的处理逻辑有所差异。在Go标准库net/http处理中,提交的同名参数将会被转换为字符串数组。

数组参数

数组参数提交格式形如:k[]=v1&k[]=v2,即以空的中括号[]来表示数组参数。

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

func main() {
	s := g.Server()
	s.BindHandler("/", func(r *ghttp.Request) {
		r.Response.Write(r.Get("array"))
	})
	s.SetPort(8199)
	s.Run()
}

执行后,我们访问 http://127.0.0.1:8199/?array[]=john&array[]=smith 后,将会得到返回值 ["john","smith"]

注意:如果传递的参数带有中括号以及索引号,那么该参数按照前面介绍的复杂参数转换规则将会被转换为map。例如,array[0]=john&array[1]=smith,将会被转换为map{"0":"john","1":"smith"}

Map参数

Map参数提交格式形如:k[a]=m&k[b]=n,并且支持多级Map,例如:k[a][a]=m&k[a][b]=n

package main

import (
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

func main() {
	s := g.Server()
	s.BindHandler("/", func(r *ghttp.Request) {
		r.Response.Write(r.Get("map"))
	})
	s.SetPort(8199)
	s.Run()
}

执行后,我们访问 http://127.0.0.1:8199/?map[id]=1&map[name]=john 后,将会得到返回值 {"id":"1","name":"john"}

我们再试试多级Map,手动访问以下地址

http://127.0.0.1:8199/?map[user1][id]=1&map[user1][name]=john&map[user2][id]=2&map[user2][name]=smith

将会得到返回值 {"user1":{"id":"1","name":"john"},"user2":{"id":"2","name":"smith"}}



Content Menu

  • No labels

7 Comments

  1. type AssessAnswer struct {
    WorkId int `p:"work_id" v:"required#工种ID不可为空"`
    StaffId int `p:"staff_id" v:"required#人员ID不可为空"`
    Answer []*Answers `p:"answer" v:"required#答题结果不可为空"`
    }

    type Answers struct {
    QuestionId int `p:"question_id" v:"required#题目ID不可为空"` // 题目ID
    Answer string `p:"answer" v:"required#题目答题结果不可为空"` // 答案
    Type int `p:"type"`
    }

    您好这样的数据 怎么接收 parseForm 只解析出了第一层



    1. 框架用的什么版本?


      1. github.com/gogf/gf v1.16.6
  2. 前端提交

    sorts[0][id]: 4
    sorts[0][index]: 31
    sorts[1][id]: 3
    sorts[1][index]: 30
    sorts[2][id]: 5
    sorts[2][index]: 29
    sorts[3][id]: 6
    sorts[3][index]: 28
    sorts[4][id]: 28
    sorts[4][index]: 27
    sorts[5][id]: 20
    sorts[5][index]: 26
    sorts[6][id]: 21
    sorts[6][index]: 25
    sorts[7][id]: 22
    sorts[7][index]: 24
    sorts[8][id]: 23
    sorts[8][index]: 23
    sorts[9][id]: 24
    sorts[9][index]: 22
    sorts[10][id]: 25
    sorts[10][index]: 21
    sorts[11][id]: 26
    sorts[11][index]: 20
    sorts[12][id]: 27
    sorts[12][index]: 19
    sorts[13][id]: 17
    sorts[13][index]: 18
    sorts[14][id]: 29
    sorts[14][index]: 17
    sorts[15][id]: 30
    sorts[15][index]: 16
    sorts[16][id]: 41
    sorts[16][index]: 15
    sorts[17][id]: 42
    sorts[17][index]: 14
    sorts[18][id]: 19
    sorts[18][index]: 13
    sorts[19][id]: 18
    sorts[19][index]: 12
    sorts[20][id]: 1
    sorts[20][index]: 11
    sorts[21][id]: 16
    sorts[21][index]: 10
    sorts[22][id]: 15
    sorts[22][index]: 9
    sorts[23][id]: 14
    sorts[23][index]: 8
    sorts[24][id]: 13
    sorts[24][index]: 7
    sorts[25][id]: 12
    sorts[25][index]: 6
    sorts[26][id]: 11
    sorts[26][index]: 5
    sorts[27][id]: 10
    sorts[27][index]: 4
    sorts[28][id]: 9
    sorts[28][index]: 3
    sorts[29][id]: 8
    sorts[29][index]: 2
    sorts[30][id]: 7
    sorts[30][index]: 1
    sorts[31][id]: 2
    sorts[31][index]: 0

    是一个数组上来,前端结构

    { sorts: { id: number; index: number }[] }

    后台定义的结构

    type FundSortStruct struct {
    	Id    int `p:"id" json:"id"`
    	Index int `p:"index" json:"index"`
    }
    
    type FundSortReq struct {
    	g.Meta `path:"/fund/sort" tags:"CrxFundSort" method:"post"`
    	Sorts  []FundSortStruct `p:"sorts" v:"required#排序参数不可为空" json:"sorts"`
    }

    但后台无法接收解析req里的sorts.如果sorts不是一个数组,只是纯结构体没问题,我想问下,前端提交的是一个数组。gf后端应如何定义接收处理呢!

    func (c *cFund) Sort(ctx context.Context, req *apiCrx.FundSortReq) (res *apiCrx.FundSortRes, err error) {
    	g.Dump(req)
    	
    	return
    }

    打印结果

    {
        Sorts: [
            {
                Id:    0,
                Index: 0,
            },
        ],
    }
    
    

    这不是我想要的结果。

    1. 请提在github主库提交issue,并粘贴可运行的最小代码。

  3. 萌新礼貌求问


    这里不是说如果带有中括号以及索引号才会按照复杂参数转换规则转为map吗?

    那为什么下面的例子没有带索引号也会转为map类型呀?

    1. Variable 这一列都是 map 类型,其中的  k 表示 map 类型中的 key, n、[m n] 等等表示map 类型中key 对应的值。