本章节的复杂参数针对于传统的 Query 或者 Form 参数传递,由于这两种参数传递方式对复杂参数传递的管理维护不是很优雅,因为我们推荐大家遇到复杂参数传递的场景尽量使用 JSON 数据编码来管理维护。
复杂参数
ghttp.Request 对象支持智能的参数类型解析(不区分请求提交方式及请求提交类型),以下为提交参数示例以及服务端对应解析的变量类型:
| Parameter | Variable |
|---|---|
k=m&k=n | map[k:n] |
k1=m&k2=n | map[k1:m k2:n] |
k[]=m&k[]=n | map[k:[m n]] |
k[a][]=m&k[a][]=n | map[k:map[a:[m n]]] |
k[a]=m&k[b]=n | map[k:map[a:m b:n]] |
k[a][a]=m&k[a][b]=n | map[k:map[a:map[a:m b:n]]] |
k=m&k[a]=n | error |
同名参数
同名参数提交格式形如: 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,手动访问以下地址
将会得到返回值 {"user1":{"id":"1","name":"john"},"user2":{"id":"2","name":"smith"}} 。
Header参数
通过GetHeader方法获取HTTP请求头信息。
方法定义:
func (r *Request) GetHeader(key string, def ...string) string
该方法根据给定的键名 key 获取请求头的值。如果指定的请求头不存在,则返回可选的默认值 def。
版本信息: 默认值参数支持从 v2.10.0 版本开始提供。
使用示例:
package main
import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
)
func main() {
s := g.Server()
s.BindHandler("/header", func(r *ghttp.Request) {
// 获取请求头,如果不存在则返回空字符串
userAgent := r.GetHeader("User-Agent")
// 获取请求头,如果不存在则返回默认值
customHeader := r.GetHeader("X-Custom-Header", "default-value")
r.Response.Writef("User-Agent: %s\n", userAgent)
r.Response.Writef("X-Custom-Header: %s\n", customHeader)
})
s.SetPort(8199)
s.Run()
}
执行后,我们通过 curl 工具进行测试:
$ curl -H "X-Custom-Header: my-value" http://127.0.0.1:8199/header
User-Agent: curl/7.68.0
X-Custom-Header: my-value
$ curl http://127.0.0.1:8199/header
User-Agent: curl/7.68.0
X-Custom-Header: default-value
可以看到,当客户端没有传递 X-Custom-Header 请求头时,GetHeader 方法返回了我们设置的默认值 default-value。