diff --git a/.example/database/gdb/mysql/gdb_update_field.go b/.example/database/gdb/mysql/gdb_update_field.go
new file mode 100644
index 000000000..c824f4176
--- /dev/null
+++ b/.example/database/gdb/mysql/gdb_update_field.go
@@ -0,0 +1,34 @@
+package main
+
+import (
+ "database/sql"
+
+ "github.com/gogf/gf/os/gfile"
+
+ "github.com/gogf/gf/encoding/gjson"
+ "github.com/gogf/gf/frame/g"
+)
+
+func main() {
+ db := g.DB()
+ table := "medicine_clinics_upload_yinchuan"
+ list, err := db.Table(table).All()
+ if err != nil && err != sql.ErrNoRows {
+ panic(err)
+ }
+ content := ""
+ for _, item := range list {
+ if j, err := gjson.DecodeToJson(item["upload_data"].String()); err != nil {
+ panic(err)
+ } else {
+ s, _ := j.ToJsonIndentString()
+ content += item["id"].String() + "\t" + item["medicine_clinic_id"].String() + "\t"
+ content += s
+ content += "\n\n"
+ //if _, err := db.Table(table).Data("data_decode", s).Where("id", item["id"].Int()).Update(); err != nil {
+ // panic(err)
+ //}
+ }
+ }
+ gfile.PutContents("/Users/john/Temp/medicine_clinics_upload_yinchuan.txt", content)
+}
diff --git a/.example/database/gdb/mysql/gdb_value.go b/.example/database/gdb/mysql/gdb_value.go
index b076054b5..b95918549 100644
--- a/.example/database/gdb/mysql/gdb_value.go
+++ b/.example/database/gdb/mysql/gdb_value.go
@@ -8,7 +8,6 @@ import (
func main() {
db := g.DB()
- // 开启调试模式,以便于记录所有执行的SQL
db.SetDebug(true)
r, e := db.Table("test").Where("id IN (?)", []interface{}{1, 2}).All()
diff --git a/.example/net/ghttp/server/form/form.go b/.example/net/ghttp/server/form/form.go
new file mode 100644
index 000000000..6731f64c2
--- /dev/null
+++ b/.example/net/ghttp/server/form/form.go
@@ -0,0 +1,16 @@
+package main
+
+import (
+ "github.com/gogf/gf/frame/g"
+ "github.com/gogf/gf/net/ghttp"
+)
+
+func main() {
+ s := g.Server()
+ s.BindHandler("/", func(r *ghttp.Request) {
+ g.Dump(r.GetPostMap())
+ r.Response.WriteTpl("form.html")
+ })
+ s.SetPort(8199)
+ s.Run()
+}
diff --git a/.example/net/ghttp/server/form/form.html b/.example/net/ghttp/server/form/form.html
new file mode 100644
index 000000000..2619de805
--- /dev/null
+++ b/.example/net/ghttp/server/form/form.html
@@ -0,0 +1,30 @@
+
+
+
+ form test
+
+
+form1
+
+
+form2
+
+
\ No newline at end of file
diff --git a/.example/other/test.go b/.example/other/test.go
index 788987ae4..ed808bf92 100644
--- a/.example/other/test.go
+++ b/.example/other/test.go
@@ -2,10 +2,15 @@ package main
import (
"fmt"
+ "reflect"
+
+ "github.com/gogf/gf/frame/g"
"github.com/gogf/gf/text/gstr"
)
func main() {
- fmt.Println(gstr.CamelCase("userLoginLog.bak"))
+ m, _ := gstr.Parse("map[a]=1&map[b]=2")
+ g.Dump(m)
+ fmt.Println(reflect.TypeOf(m["map"].(map[string]interface{})["b"]))
}
diff --git a/go.sum b/go.sum
index 6219984df..10b37e2ef 100644
--- a/go.sum
+++ b/go.sum
@@ -6,15 +6,21 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/gf-third/mysql v1.4.2 h1:f1M5CNFUG3WkE07UOomtu4o0n/KJKeuUUf5Nc9ZFXs4=
github.com/gf-third/mysql v1.4.2/go.mod h1:+dd90V663ppI2fV5uQ6+rHk0u8KCyU6FkG8Um8Cx3ms=
github.com/gf-third/yaml/v3 v3.0.0 h1:IMLH3JWFpNraTz5d6jzaNZFvWaVYAwhP9w1lhk9SFUs=
github.com/gf-third/yaml/v3 v3.0.0/go.mod h1:En6jd9ZtAhuCiVfRnTo8NYVgbiZvg/F26r8Tj+vsUy4=
github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
+github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/grokify/html-strip-tags-go v0.0.0-20190916062342-6f856a90d556 h1:RS7ewakEriTcISIy+USQV9tE37SpWCblCiPE6QWxagk=
github.com/grokify/html-strip-tags-go v0.0.0-20190916062342-6f856a90d556/go.mod h1:Xk7G0nwBiIloTMbLddk4WWJOqi4i/JLhadLd0HUXO30=
+github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/olekukonko/tablewriter v0.0.1 h1:b3iUnf1v+ppJiOfNX4yxxqfWKMQPZR5yoh8urCTFX88=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/theckman/go-flock v0.7.1/go.mod h1:kjuth3y9VJ2aNlkNEO99G/8lp9fMIKaGyBmh84IBheM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
diff --git a/net/ghttp/ghttp_request.go b/net/ghttp/ghttp_request.go
index 55b041d3a..f5dcce3e7 100644
--- a/net/ghttp/ghttp_request.go
+++ b/net/ghttp/ghttp_request.go
@@ -38,8 +38,11 @@ type Request struct {
hasServeHandler bool // 是否检索到服务函数
parsedGet bool // GET参数是否已经解析
parsedPost bool // POST参数是否已经解析
- queryVars map[string][]string // GET参数
- routerVars map[string][]string // 路由解析参数
+ parsedRaw bool // 原始参数是否已经解析
+ getMap map[string]interface{} // GET解析参数
+ postMap map[string]interface{} // POST解析参数
+ routerMap map[string]interface{} // 路由解析参数
+ rawVarMap map[string]interface{} // 原始数据参数
error error // 当前请求执行错误
exit bool // 是否退出当前请求流程执行
params map[string]interface{} // 开发者自定义参数(请求流程中有效)
@@ -52,12 +55,12 @@ type Request struct {
// 创建一个Request对象
func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request {
request := &Request{
- routerVars: make(map[string][]string),
- Id: s.servedCount.Add(1),
- Server: s,
- Request: r,
- Response: newResponse(s, w),
- EnterTime: gtime.Microsecond(),
+ routerMap: make(map[string]interface{}),
+ Id: s.servedCount.Add(1),
+ Server: s,
+ Request: r,
+ Response: newResponse(s, w),
+ EnterTime: gtime.Microsecond(),
}
// 会话处理
request.Cookie = GetCookie(request)
@@ -82,8 +85,8 @@ func (r *Request) WebSocket() (*WebSocket, error) {
// 获得指定名称的参数字符串(Router/GET/POST),同 GetRequestString
// 这是常用方法的简化别名
-func (r *Request) Get(key string, def ...interface{}) string {
- return r.GetRequestString(key, def...)
+func (r *Request) Get(key string, def ...interface{}) interface{} {
+ return r.GetRequest(key, def...)
}
// 建议都用该参数替代参数获取
@@ -113,6 +116,10 @@ func (r *Request) GetString(key string, def ...interface{}) string {
return r.GetRequestString(key, def...)
}
+func (r *Request) GetBool(key string, def ...interface{}) bool {
+ return r.GetRequestBool(key, def...)
+}
+
func (r *Request) GetInt(key string, def ...interface{}) int {
return r.GetRequestInt(key, def...)
}
@@ -149,7 +156,7 @@ func (r *Request) GetInterfaces(key string, def ...interface{}) []interface{} {
return r.GetRequestInterfaces(key, def...)
}
-func (r *Request) GetMap(def ...map[string]string) map[string]string {
+func (r *Request) GetMap(def ...map[string]interface{}) map[string]interface{} {
return r.GetRequestMap(def...)
}
@@ -236,14 +243,6 @@ func (r *Request) GetSessionId() string {
return id
}
-// 生成随机的SESSIONID
-func (r *Request) MakeSessionId() string {
- id := gsession.NewSessionId()
- r.Cookie.SetSessionId(id)
- r.Response.Header().Set(r.Server.GetSessionIdName(), id)
- return id
-}
-
// 获得请求来源URL地址
func (r *Request) GetReferer() string {
return r.Header.Get("Referer")
diff --git a/net/ghttp/ghttp_request_middleware.go b/net/ghttp/ghttp_request_middleware.go
index 746ae690b..39d1b3631 100644
--- a/net/ghttp/ghttp_request_middleware.go
+++ b/net/ghttp/ghttp_request_middleware.go
@@ -38,7 +38,7 @@ func (m *Middleware) Next() {
}
// 路由参数赋值
for k, v := range item.values {
- m.request.routerVars[k] = v
+ m.request.routerMap[k] = v
}
m.request.Router = item.handler.router
// 执行函数处理
diff --git a/net/ghttp/ghttp_request_params.go b/net/ghttp/ghttp_request_params.go
index 9cbdc41d3..42257db2e 100644
--- a/net/ghttp/ghttp_request_params.go
+++ b/net/ghttp/ghttp_request_params.go
@@ -17,14 +17,17 @@ func (r *Request) SetParam(key string, value interface{}) {
}
// 获取请求流程共享变量
-func (r *Request) GetParam(key string, def ...interface{}) *gvar.Var {
+func (r *Request) GetParam(key string, def ...interface{}) interface{} {
if r.params != nil {
- if v, ok := r.params[key]; ok {
- return gvar.New(v)
- }
+ return r.params[key]
}
if len(def) > 0 {
- return gvar.New(def[0])
+ return def[0]
}
- return gvar.New(nil)
+ return nil
+}
+
+// 获取请求流程共享变量
+func (r *Request) GetParamVar(key string, def ...interface{}) *gvar.Var {
+ return gvar.New(r.GetParam(key, def...))
}
diff --git a/net/ghttp/ghttp_request_post.go b/net/ghttp/ghttp_request_post.go
index d740ef76d..9d852c2fa 100644
--- a/net/ghttp/ghttp_request_post.go
+++ b/net/ghttp/ghttp_request_post.go
@@ -7,156 +7,153 @@
package ghttp
import (
+ "strings"
+
+ "github.com/gogf/gf/encoding/gurl"
+
"github.com/gogf/gf/container/gvar"
"github.com/gogf/gf/internal/structs"
+ "github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
)
// 初始化POST请求参数
func (r *Request) initPost() {
if !r.parsedPost {
- // MultiMedia表单请求解析允许最大使用内存:1GB
- if r.ParseMultipartForm(1024*1024*1024) == nil {
- r.parsedPost = true
+ r.parsedPost = true
+ if v := r.Header.Get("Content-Type"); v != "" && gstr.Contains(v, "multipart/") {
+ // multipart/form-data, multipart/mixed
+ // MultiMedia表单请求解析允许最大使用内存:1GB
+ r.ParseMultipartForm(1024 * 1024 * 1024)
+ if len(r.PostForm) > 0 {
+ // 重新组织数据格式,使用统一的数据Parse方式
+ params := ""
+ for name, values := range r.PostForm {
+ if len(values) == 1 {
+ if len(params) > 0 {
+ params += "&"
+ }
+ params += name + "=" + gurl.Encode(values[0])
+ } else {
+ if len(name) > 2 && name[len(name)-2:] == "[]" {
+ name = name[:len(name)-2]
+ for _, v := range values {
+ if len(params) > 0 {
+ params += "&"
+ }
+ params += name + "[]=" + gurl.Encode(v)
+ }
+ } else {
+ if len(params) > 0 {
+ params += "&"
+ }
+ params += name + "=" + gurl.Encode(values[len(values)-1])
+ }
+ }
+ }
+ r.postMap, _ = gstr.Parse(params)
+ }
+ } else if strings.EqualFold(r.Method, "POST") {
+ r.parsedRaw = true
+ if raw := r.GetRawString(); len(raw) > 0 {
+ r.postMap, _ = gstr.Parse(raw)
+ }
}
}
}
-// 设置POST参数,仅在ghttp.Server内有效,**注意并发安全性**
-func (r *Request) SetPost(key string, value string) {
+// 设置当前请求的POST参数
+func (r *Request) SetPost(key string, value interface{}) {
r.initPost()
- r.PostForm[key] = []string{value}
+ r.postMap[key] = value
}
-func (r *Request) AddPost(key string, value string) {
+func (r *Request) GetPost(key string, def ...interface{}) interface{} {
r.initPost()
- r.PostForm[key] = append(r.PostForm[key], value)
-}
-
-func (r *Request) GetPost(key string, def ...interface{}) []string {
- r.initPost()
- if v, ok := r.PostForm[key]; ok {
+ if v, ok := r.postMap[key]; ok {
return v
}
if len(def) > 0 {
- return gconv.Strings(def[0])
+ return def[0]
}
return nil
}
func (r *Request) GetPostVar(key string, def ...interface{}) *gvar.Var {
- return gvar.New(r.GetPostString(key, def...))
+ return gvar.New(r.GetPost(key, def...))
}
func (r *Request) GetPostString(key string, def ...interface{}) string {
- value := r.GetPost(key, def...)
- if value != nil && value[0] != "" {
- return value[0]
- }
- return ""
+ return r.GetPostVar(key, def...).String()
}
func (r *Request) GetPostBool(key string, def ...interface{}) bool {
- value := r.GetPostString(key, def...)
- if value != "" {
- return gconv.Bool(value)
- }
- return false
+ return r.GetPostVar(key, def...).Bool()
}
func (r *Request) GetPostInt(key string, def ...interface{}) int {
- value := r.GetPostString(key, def...)
- if value != "" {
- return gconv.Int(value)
- }
- return 0
+ return r.GetPostVar(key, def...).Int()
}
func (r *Request) GetPostInts(key string, def ...interface{}) []int {
- value := r.GetPost(key, def...)
- if value != nil {
- return gconv.Ints(value)
- }
- return nil
+ return r.GetPostVar(key, def...).Ints()
}
func (r *Request) GetPostUint(key string, def ...interface{}) uint {
- value := r.GetPostString(key, def...)
- if value != "" {
- return gconv.Uint(value)
- }
- return 0
+ return r.GetPostVar(key, def...).Uint()
}
func (r *Request) GetPostFloat32(key string, def ...interface{}) float32 {
- value := r.GetPostString(key, def...)
- if value != "" {
- return gconv.Float32(value)
- }
- return 0
+ return r.GetPostVar(key, def...).Float32()
}
func (r *Request) GetPostFloat64(key string, def ...interface{}) float64 {
- value := r.GetPostString(key, def...)
- if value != "" {
- return gconv.Float64(value)
- }
- return 0
+ return r.GetPostVar(key, def...).Float64()
}
func (r *Request) GetPostFloats(key string, def ...interface{}) []float64 {
- value := r.GetPost(key, def...)
- if value != nil {
- return gconv.Floats(value)
- }
- return nil
+ return r.GetPostVar(key, def...).Floats()
}
func (r *Request) GetPostArray(key string, def ...interface{}) []string {
- return r.GetPost(key, def...)
+ return r.GetPostVar(key, def...).Strings()
}
func (r *Request) GetPostStrings(key string, def ...interface{}) []string {
- return r.GetPost(key, def...)
+ return r.GetPostVar(key, def...).Strings()
}
func (r *Request) GetPostInterfaces(key string, def ...interface{}) []interface{} {
- value := r.GetPost(key, def...)
- if value != nil {
- return gconv.Interfaces(value)
- }
- return nil
+ return r.GetPostVar(key, def...).Interfaces()
}
-// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值
-// 需要注意的是,如果其中一个字段为数组形式,那么只会返回第一个元素,如果需要获取全部的元素,请使用GetPostArray获取特定字段内容
-func (r *Request) GetPostMap(def ...map[string]string) map[string]string {
+// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值。
+// 当不指定键值对关联数组时,默认获取POST方式提交的所有的提交键值对数据。
+func (r *Request) GetPostMap(kvMap ...map[string]interface{}) map[string]interface{} {
r.initPost()
- m := make(map[string]string)
- for k, v := range r.PostForm {
- m[k] = v[0]
- }
- if len(def) > 0 {
- for k, v := range def[0] {
- if _, ok := m[k]; !ok {
- m[k] = v
+ if len(kvMap) > 0 {
+ m := make(map[string]interface{})
+ for k, defValue := range kvMap[0] {
+ if postValue, ok := r.postMap[k]; ok {
+ m[k] = postValue
+ } else {
+ m[k] = defValue
}
}
+ return m
+ } else {
+ return r.postMap
}
- return m
}
// 将所有的request参数映射到struct属性上,参数object应当为一个struct对象的指针, mapping为非必需参数,自定义参数与属性的映射关系
func (r *Request) GetPostToStruct(pointer interface{}, mapping ...map[string]string) error {
+ r.initPost()
tagMap := structs.TagMapName(pointer, paramTagPriority, true)
if len(mapping) > 0 {
for k, v := range mapping[0] {
tagMap[k] = v
}
}
- params := make(map[string]interface{})
- for k, v := range r.GetPostMap() {
- params[k] = v
- }
- return gconv.StructDeep(params, pointer, tagMap)
+ return gconv.StructDeep(r.postMap, pointer, tagMap)
}
diff --git a/net/ghttp/ghttp_request_query.go b/net/ghttp/ghttp_request_query.go
index 53e08eaab..ab1860f50 100644
--- a/net/ghttp/ghttp_request_query.go
+++ b/net/ghttp/ghttp_request_query.go
@@ -9,6 +9,8 @@ package ghttp
import (
"strings"
+ "github.com/gogf/gf/text/gstr"
+
"github.com/gogf/gf/container/gvar"
"github.com/gogf/gf/internal/structs"
@@ -18,156 +20,111 @@ import (
// 初始化GET请求参数
func (r *Request) initGet() {
if !r.parsedGet {
- r.queryVars = r.URL.Query()
- if strings.EqualFold(r.Method, "GET") {
+ r.parsedGet = true
+ if r.URL.RawQuery != "" {
+ r.getMap, _ = gstr.Parse(r.URL.RawQuery)
+ } else if strings.EqualFold(r.Method, "GET") {
+ r.parsedRaw = true
if raw := r.GetRawString(); len(raw) > 0 {
- var array []string
- for _, item := range strings.Split(raw, "&") {
- array = strings.Split(item, "=")
- r.queryVars[array[0]] = append(r.queryVars[array[0]], array[1])
- }
+ r.getMap, _ = gstr.Parse(raw)
}
}
- r.parsedGet = true
}
}
-// 设置GET参数,仅在ghttp.Server内有效,**注意并发安全性**
-func (r *Request) SetQuery(key string, value string) {
+// 设置当前请求的GET参数
+func (r *Request) SetQuery(key string, value interface{}) {
r.initGet()
- r.queryVars[key] = []string{value}
-}
-
-// 添加GET参数,构成[]string
-func (r *Request) AddQuery(key string, value string) {
- r.initGet()
- r.queryVars[key] = append(r.queryVars[key], value)
+ r.getMap[key] = value
}
// 获得指定名称的get参数列表
-func (r *Request) GetQuery(key string, def ...interface{}) []string {
+func (r *Request) GetQuery(key string, def ...interface{}) interface{} {
r.initGet()
- if v, ok := r.queryVars[key]; ok {
+ if v, ok := r.getMap[key]; ok {
return v
}
if len(def) > 0 {
- return gconv.Strings(def[0])
+ return def[0]
}
return nil
}
func (r *Request) GetQueryVar(key string, def ...interface{}) *gvar.Var {
- return gvar.New(r.GetQueryString(key, def...))
+ return gvar.New(r.GetQuery(key, def...))
}
func (r *Request) GetQueryString(key string, def ...interface{}) string {
- value := r.GetQuery(key, def...)
- if value != nil && value[0] != "" {
- return value[0]
- }
- return ""
+ return r.GetQueryVar(key, def...).String()
}
func (r *Request) GetQueryBool(key string, def ...interface{}) bool {
- value := r.GetQueryString(key, def...)
- if value != "" {
- return gconv.Bool(value)
- }
- return false
+ return r.GetQueryVar(key, def...).Bool()
}
func (r *Request) GetQueryInt(key string, def ...interface{}) int {
- value := r.GetQueryString(key, def...)
- if value != "" {
- return gconv.Int(value)
- }
- return 0
+ return r.GetQueryVar(key, def...).Int()
}
func (r *Request) GetQueryInts(key string, def ...interface{}) []int {
- value := r.GetQuery(key, def...)
- if value != nil {
- return gconv.Ints(value)
- }
- return nil
+ return r.GetQueryVar(key, def...).Ints()
}
func (r *Request) GetQueryUint(key string, def ...interface{}) uint {
- value := r.GetQueryString(key, def...)
- if value != "" {
- return gconv.Uint(value)
- }
- return 0
+ return r.GetQueryVar(key, def...).Uint()
}
func (r *Request) GetQueryFloat32(key string, def ...interface{}) float32 {
- value := r.GetQueryString(key, def...)
- if value != "" {
- return gconv.Float32(value)
- }
- return 0
+ return r.GetQueryVar(key, def...).Float32()
}
func (r *Request) GetQueryFloat64(key string, def ...interface{}) float64 {
- value := r.GetQueryString(key, def...)
- if value != "" {
- return gconv.Float64(value)
- }
- return 0
+ return r.GetQueryVar(key, def...).Float64()
}
func (r *Request) GetQueryFloats(key string, def ...interface{}) []float64 {
- value := r.GetQuery(key, def...)
- if value != nil {
- return gconv.Floats(value)
- }
- return nil
+ return r.GetQueryVar(key, def...).Floats()
}
func (r *Request) GetQueryArray(key string, def ...interface{}) []string {
- return r.GetQuery(key, def...)
+ return r.GetQueryVar(key, def...).Strings()
}
func (r *Request) GetQueryStrings(key string, def ...interface{}) []string {
- return r.GetQuery(key, def...)
+ return r.GetQueryVar(key, def...).Strings()
}
func (r *Request) GetQueryInterfaces(key string, def ...interface{}) []interface{} {
- value := r.GetQuery(key, def...)
- if value != nil {
- return gconv.Interfaces(value)
- }
- return nil
+ return r.GetQueryVar(key, def...).Interfaces()
}
-// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值
-func (r *Request) GetQueryMap(def ...map[string]string) map[string]string {
+// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值。
+// 当不指定键值对关联数组时,默认获取GET方式提交的所有的提交键值对数据。
+func (r *Request) GetQueryMap(kvMap ...map[string]interface{}) map[string]interface{} {
r.initGet()
- m := make(map[string]string)
- for k, v := range r.queryVars {
- m[k] = v[0]
- }
- if len(def) > 0 {
- for k, v := range def[0] {
- if _, ok := m[k]; !ok {
- m[k] = v
+ if len(kvMap) > 0 {
+ m := make(map[string]interface{})
+ for k, defValue := range kvMap[0] {
+ if queryValue, ok := r.getMap[k]; ok {
+ m[k] = queryValue
+ } else {
+ m[k] = defValue
}
}
+ return m
+ } else {
+ return r.getMap
}
- return m
}
// 将所有的get参数映射到struct属性上,参数object应当为一个struct对象的指针, mapping为非必需参数,自定义参数与属性的映射关系
func (r *Request) GetQueryToStruct(pointer interface{}, mapping ...map[string]string) error {
- tagmap := structs.TagMapName(pointer, paramTagPriority, true)
+ r.initGet()
+ tagMap := structs.TagMapName(pointer, paramTagPriority, true)
if len(mapping) > 0 {
for k, v := range mapping[0] {
- tagmap[k] = v
+ tagMap[k] = v
}
}
- params := make(map[string]interface{})
- for k, v := range r.GetQueryMap() {
- params[k] = v
- }
- return gconv.StructDeep(params, pointer, tagmap)
+ return gconv.StructDeep(r.getMap, pointer, tagMap)
}
diff --git a/net/ghttp/ghttp_request_request.go b/net/ghttp/ghttp_request_request.go
index 050d97858..c965064d8 100644
--- a/net/ghttp/ghttp_request_request.go
+++ b/net/ghttp/ghttp_request_request.go
@@ -9,126 +9,112 @@ package ghttp
import (
"github.com/gogf/gf/container/gvar"
"github.com/gogf/gf/internal/structs"
+ "github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
)
+// 初始化RAW请求参数
+func (r *Request) initRaw() {
+ if !r.parsedRaw {
+ r.parsedRaw = true
+ if raw := r.GetRawString(); len(raw) > 0 {
+ r.rawVarMap, _ = gstr.Parse(raw)
+ }
+ }
+}
+
// 获得router、post或者get提交的参数,如果有同名参数,那么按照router->get->post优先级进行覆盖
-func (r *Request) GetRequest(key string, def ...interface{}) []string {
- v := r.GetRouterArray(key)
+func (r *Request) GetRequest(key string, def ...interface{}) interface{} {
+ v := r.GetRouterValue(key)
if v == nil {
v = r.GetQuery(key)
}
if v == nil {
v = r.GetPost(key)
}
+ if v != nil {
+ return v
+ }
+ r.initRaw()
+ v = r.rawVarMap[key]
if v == nil && len(def) > 0 {
- return gconv.Strings(def[0])
+ return def[0]
}
return v
}
func (r *Request) GetRequestVar(key string, def ...interface{}) *gvar.Var {
- value := r.GetRequest(key, def...)
- if value != nil {
- return gvar.New(value[0])
- }
- return gvar.New(nil)
+ return gvar.New(r.GetRequest(key, def...))
}
func (r *Request) GetRequestString(key string, def ...interface{}) string {
- value := r.GetRequest(key, def...)
- if value != nil && value[0] != "" {
- return value[0]
- }
- return ""
+ return r.GetRequestVar(key, def...).String()
}
func (r *Request) GetRequestBool(key string, def ...interface{}) bool {
- value := r.GetRequestString(key, def...)
- if value != "" {
- return gconv.Bool(value)
- }
- return false
+ return r.GetRequestVar(key, def...).Bool()
}
func (r *Request) GetRequestInt(key string, def ...interface{}) int {
- value := r.GetRequestString(key, def...)
- if value != "" {
- return gconv.Int(value)
- }
- return 0
+ return r.GetRequestVar(key, def...).Int()
}
func (r *Request) GetRequestInts(key string, def ...interface{}) []int {
- value := r.GetRequest(key, def...)
- if value != nil {
- return gconv.Ints(value)
- }
- return nil
+ return r.GetRequestVar(key, def...).Ints()
}
func (r *Request) GetRequestUint(key string, def ...interface{}) uint {
- value := r.GetRequestString(key, def...)
- if value != "" {
- return gconv.Uint(value)
- }
- return 0
+ return r.GetRequestVar(key, def...).Uint()
}
func (r *Request) GetRequestFloat32(key string, def ...interface{}) float32 {
- value := r.GetRequestString(key, def...)
- if value != "" {
- return gconv.Float32(value)
- }
- return 0
+ return r.GetRequestVar(key, def...).Float32()
}
func (r *Request) GetRequestFloat64(key string, def ...interface{}) float64 {
- value := r.GetRequestString(key, def...)
- if value != "" {
- return gconv.Float64(value)
- }
- return 0
+ return r.GetRequestVar(key, def...).Float64()
}
func (r *Request) GetRequestFloats(key string, def ...interface{}) []float64 {
- value := r.GetRequest(key, def...)
- if value != nil {
- return gconv.Floats(value)
- }
- return nil
+ return r.GetRequestVar(key, def...).Floats()
}
func (r *Request) GetRequestArray(key string, def ...interface{}) []string {
- return r.GetRequest(key, def...)
+ return r.GetRequestVar(key, def...).Strings()
}
func (r *Request) GetRequestStrings(key string, def ...interface{}) []string {
- return r.GetRequest(key, def...)
+ return r.GetRequestVar(key, def...).Strings()
}
func (r *Request) GetRequestInterfaces(key string, def ...interface{}) []interface{} {
- value := r.GetRequest(key, def...)
- if value != nil {
- return gconv.Interfaces(value)
- }
- return nil
+ return r.GetRequestVar(key, def...).Interfaces()
}
// 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值
// 需要注意的是,如果其中一个字段为数组形式,那么只会返回第一个元素,如果需要获取全部的元素,请使用GetRequestArray获取特定字段内容
-func (r *Request) GetRequestMap(def ...map[string]string) map[string]string {
- m := r.GetQueryMap()
- if len(m) == 0 {
- m = r.GetPostMap()
- }
- if len(def) > 0 {
- for k, v := range def[0] {
- if _, ok := m[k]; !ok {
- m[k] = v
+func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]interface{} {
+ r.initRaw()
+ m := r.rawVarMap
+ if len(kvMap) > 0 {
+ m = make(map[string]interface{})
+ for k, defValue := range kvMap[0] {
+ if rawValue, ok := r.rawVarMap[k]; ok {
+ m[k] = rawValue
+ } else {
+ m[k] = defValue
}
}
}
+ if m == nil {
+ m = make(map[string]interface{})
+ }
+ for k, v := range r.GetPostMap(kvMap...) {
+ m[k] = v
+ }
+ for k, v := range r.GetQueryMap(kvMap...) {
+ m[k] = v
+ }
return m
}
@@ -140,14 +126,5 @@ func (r *Request) GetRequestToStruct(pointer interface{}, mapping ...map[string]
tagMap[k] = v
}
}
- params := make(map[string]interface{})
- for k, v := range r.GetRequestMap() {
- params[k] = v
- }
- if len(params) == 0 {
- if j := r.GetJson(); j != nil {
- params = j.ToMap()
- }
- }
- return gconv.StructDeep(params, pointer, tagMap)
+ return gconv.StructDeep(r.GetRequestMap(), pointer, tagMap)
}
diff --git a/net/ghttp/ghttp_request_router.go b/net/ghttp/ghttp_request_router.go
index 1e99c523a..70e85f693 100644
--- a/net/ghttp/ghttp_request_router.go
+++ b/net/ghttp/ghttp_request_router.go
@@ -6,26 +6,24 @@
package ghttp
-func (r *Request) SetRouterString(key, value string) {
- r.routerVars[key] = []string{value}
-}
+import "github.com/gogf/gf/container/gvar"
-func (r *Request) AddRouterString(key, value string) {
- r.routerVars[key] = append(r.routerVars[key], value)
+func (r *Request) SetRouterValue(key string, value interface{}) {
+ r.routerMap[key] = value
}
// 获得路由解析参数
-func (r *Request) GetRouterString(key string) string {
- if v := r.GetRouterArray(key); v != nil {
- return v[0]
+func (r *Request) GetRouterValue(key string, def ...interface{}) interface{} {
+ if r.routerMap != nil {
+ return r.routerMap[key]
}
- return ""
-}
-
-// 获得路由解析参数
-func (r *Request) GetRouterArray(key string) []string {
- if v, ok := r.routerVars[key]; ok {
- return v
+ if len(def) > 0 {
+ return def[0]
}
return nil
}
+
+// 获得路由解析参数, gvar.Var
+func (r *Request) GetRouterVar(key string, def ...interface{}) *gvar.Var {
+ return gvar.New(r.GetRouterValue(key, def...))
+}
diff --git a/net/ghttp/ghttp_response.go b/net/ghttp/ghttp_response.go
index 4518a3e25..8cfa248a9 100644
--- a/net/ghttp/ghttp_response.go
+++ b/net/ghttp/ghttp_response.go
@@ -99,7 +99,7 @@ func (r *Response) WriteJsonP(content interface{}) error {
return err
} else {
//r.Header().Set("Content-Type", "application/json")
- if callback := r.request.Get("callback"); callback != "" {
+ if callback := r.request.GetString("callback"); callback != "" {
buffer := []byte(callback)
buffer = append(buffer, byte('('))
buffer = append(buffer, b...)
diff --git a/net/ghttp/ghttp_server.go b/net/ghttp/ghttp_server.go
index e42a14002..a23697432 100644
--- a/net/ghttp/ghttp_server.go
+++ b/net/ghttp/ghttp_server.go
@@ -75,8 +75,8 @@ type (
// 根据特定URL.Path解析后的路由检索结果项
handlerParsedItem struct {
- handler *handlerItem // 路由注册项
- values map[string][]string // 特定URL.Path的Router解析参数
+ handler *handlerItem // 路由注册项
+ values map[string]string // 特定URL.Path的Router解析参数
}
// 控制器服务函数反射信息
diff --git a/net/ghttp/ghttp_server_pprof.go b/net/ghttp/ghttp_server_pprof.go
index b460fcca8..5ca66615b 100644
--- a/net/ghttp/ghttp_server_pprof.go
+++ b/net/ghttp/ghttp_server_pprof.go
@@ -20,7 +20,7 @@ type utilPprof struct{}
func (p *utilPprof) Index(r *Request) {
profiles := runpprof.Profiles()
- action := r.Get("action")
+ action := r.GetString("action")
data := map[string]interface{}{
"uri": strings.TrimRight(r.URL.Path, "/") + "/",
"profiles": profiles,
diff --git a/net/ghttp/ghttp_server_router_hook.go b/net/ghttp/ghttp_server_router_hook.go
index 5b3825951..581cfa4f1 100644
--- a/net/ghttp/ghttp_server_router_hook.go
+++ b/net/ghttp/ghttp_server_router_hook.go
@@ -34,20 +34,20 @@ func (s *Server) callHookHandler(hook string, r *Request) {
hookItems := r.getHookHandlers(hook)
if len(hookItems) > 0 {
// 备份原有的router变量
- oldRouterVars := r.routerVars
+ oldRouterVars := r.routerMap
for _, item := range hookItems {
// hook方法不能更改serve方法的路由参数,其匹配的路由参数只能自己使用,
// 且在多个hook方法之间不能共享路由参数,单可以使用匹配的serve方法路由参数。
// 当前回调函数的路由参数只在当前回调函数下有效。
- r.routerVars = make(map[string][]string)
+ r.routerMap = make(map[string]interface{})
if len(oldRouterVars) > 0 {
for k, v := range oldRouterVars {
- r.routerVars[k] = v
+ r.routerMap[k] = v
}
}
if len(item.values) > 0 {
for k, v := range item.values {
- r.routerVars[k] = v
+ r.routerMap[k] = v
}
}
// 不使用hook的router对象,保留路由注册服务的router对象,不能覆盖
@@ -66,7 +66,7 @@ func (s *Server) callHookHandler(hook string, r *Request) {
}
}
// 恢复原有的router变量
- r.routerVars = oldRouterVars
+ r.routerMap = oldRouterVars
}
}
diff --git a/net/ghttp/ghttp_server_router_serve.go b/net/ghttp/ghttp_server_router_serve.go
index 23a43ca59..81c76c170 100644
--- a/net/ghttp/ghttp_server_router_serve.go
+++ b/net/ghttp/ghttp_server_router_serve.go
@@ -113,14 +113,10 @@ func (s *Server) searchHandlers(method, path, domain string) (parsedItems []*han
// 如果需要query匹配,那么需要重新正则解析URL
if len(item.router.RegNames) > 0 {
if len(match) > len(item.router.RegNames) {
- parsedItem.values = make(map[string][]string)
- // 如果存在存在同名路由参数名称,那么执行数组追加
+ parsedItem.values = make(map[string]string)
+ // 如果存在存在同名路由参数名称,那么执行覆盖
for i, name := range item.router.RegNames {
- if _, ok := parsedItem.values[name]; ok {
- parsedItem.values[name] = append(parsedItem.values[name], match[i+1])
- } else {
- parsedItem.values[name] = []string{match[i+1]}
- }
+ parsedItem.values[name] = match[i+1]
}
}
}
diff --git a/net/ghttp/ghttp_unit_cookie_test.go b/net/ghttp/ghttp_unit_cookie_test.go
index af3ffaebe..bbcb53c74 100644
--- a/net/ghttp/ghttp_unit_cookie_test.go
+++ b/net/ghttp/ghttp_unit_cookie_test.go
@@ -20,14 +20,13 @@ func Test_Cookie(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
- r.Cookie.Set(r.Get("k"), r.Get("v"))
+ r.Cookie.Set(r.GetString("k"), r.GetString("v"))
})
s.BindHandler("/get", func(r *ghttp.Request) {
- //fmt.Println(r.Cookie.Map())
- r.Response.Write(r.Cookie.Get(r.Get("k")))
+ r.Response.Write(r.Cookie.Get(r.GetString("k")))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
- r.Cookie.Remove(r.Get("k"))
+ r.Cookie.Remove(r.GetString("k"))
})
s.SetPort(p)
s.SetDumpRouteMap(false)
diff --git a/net/ghttp/ghttp_unit_param_test.go b/net/ghttp/ghttp_unit_param_test.go
index 753b42884..191b5a1a3 100644
--- a/net/ghttp/ghttp_unit_param_test.go
+++ b/net/ghttp/ghttp_unit_param_test.go
@@ -48,6 +48,32 @@ func Test_Params_Basic(t *testing.T) {
r.Response.Write(r.GetQueryString("string"))
}
})
+ s.BindHandler("/put", func(r *ghttp.Request) {
+ if r.Get("slice") != nil {
+ r.Response.Write(r.Get("slice"))
+ }
+ if r.Get("bool") != nil {
+ r.Response.Write(r.GetBool("bool"))
+ }
+ if r.Get("float32") != nil {
+ r.Response.Write(r.GetFloat32("float32"))
+ }
+ if r.Get("float64") != nil {
+ r.Response.Write(r.GetFloat64("float64"))
+ }
+ if r.Get("int") != nil {
+ r.Response.Write(r.GetInt("int"))
+ }
+ if r.Get("uint") != nil {
+ r.Response.Write(r.GetUint("uint"))
+ }
+ if r.Get("string") != nil {
+ r.Response.Write(r.GetString("string"))
+ }
+ if r.Get("map") != nil {
+ r.Response.Write(r.GetMap()["map"].(map[string]interface{})["b"])
+ }
+ })
s.BindHandler("/post", func(r *ghttp.Request) {
if r.GetPost("slice") != nil {
r.Response.Write(r.GetPost("slice"))
@@ -70,6 +96,9 @@ func Test_Params_Basic(t *testing.T) {
if r.GetPost("string") != nil {
r.Response.Write(r.GetPostString("string"))
}
+ if r.GetPost("map") != nil {
+ r.Response.Write(r.GetPostMap()["map"].(map[string]interface{})["b"])
+ }
})
s.BindHandler("/map", func(r *ghttp.Request) {
if m := r.GetQueryMap(); len(m) > 0 {
@@ -132,7 +161,7 @@ func Test_Params_Basic(t *testing.T) {
client := ghttp.NewClient()
client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p))
// GET
- gtest.Assert(client.GetContent("/get", "slice=1&slice=2"), `["1","2"]`)
+ gtest.Assert(client.GetContent("/get", "slice=1&slice=2"), `2`)
gtest.Assert(client.GetContent("/get", "bool=1"), `true`)
gtest.Assert(client.GetContent("/get", "bool=0"), `false`)
gtest.Assert(client.GetContent("/get", "float32=0.11"), `0.11`)
@@ -143,8 +172,21 @@ func Test_Params_Basic(t *testing.T) {
gtest.Assert(client.GetContent("/get", "uint=9"), `9`)
gtest.Assert(client.GetContent("/get", "string=key"), `key`)
+ // PUT
+ gtest.Assert(client.PutContent("/put", "slice=1&slice=2"), `2`)
+ gtest.Assert(client.PutContent("/put", "bool=1"), `true`)
+ gtest.Assert(client.PutContent("/put", "bool=0"), `false`)
+ gtest.Assert(client.PutContent("/put", "float32=0.11"), `0.11`)
+ gtest.Assert(client.PutContent("/put", "float64=0.22"), `0.22`)
+ gtest.Assert(client.PutContent("/put", "int=-10000"), `-10000`)
+ gtest.Assert(client.PutContent("/put", "int=10000"), `10000`)
+ gtest.Assert(client.PutContent("/put", "uint=10000"), `10000`)
+ gtest.Assert(client.PutContent("/put", "uint=9"), `9`)
+ gtest.Assert(client.PutContent("/put", "string=key"), `key`)
+ gtest.Assert(client.PutContent("/put", "map[a]=1&map[b]=2"), `2`)
+
// POST
- gtest.Assert(client.PostContent("/post", "slice=1&slice=2"), `["1","2"]`)
+ gtest.Assert(client.PostContent("/post", "slice=1&slice=2"), `2`)
gtest.Assert(client.PostContent("/post", "bool=1"), `true`)
gtest.Assert(client.PostContent("/post", "bool=0"), `false`)
gtest.Assert(client.PostContent("/post", "float32=0.11"), `0.11`)
@@ -154,6 +196,7 @@ func Test_Params_Basic(t *testing.T) {
gtest.Assert(client.PostContent("/post", "uint=10000"), `10000`)
gtest.Assert(client.PostContent("/post", "uint=9"), `9`)
gtest.Assert(client.PostContent("/post", "string=key"), `key`)
+ gtest.Assert(client.PostContent("/post", "map[a]=1&map[b]=2"), `2`)
// Map
gtest.Assert(client.GetContent("/map", "id=1&name=john"), `john`)
diff --git a/net/ghttp/ghttp_unit_session_test.go b/net/ghttp/ghttp_unit_session_test.go
index 6bf92b634..64a923cf7 100644
--- a/net/ghttp/ghttp_unit_session_test.go
+++ b/net/ghttp/ghttp_unit_session_test.go
@@ -20,13 +20,13 @@ func Test_Session_Cookie(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
- r.Session.Set(r.Get("k"), r.Get("v"))
+ r.Session.Set(r.GetString("k"), r.GetString("v"))
})
s.BindHandler("/get", func(r *ghttp.Request) {
- r.Response.Write(r.Session.Get(r.Get("k")))
+ r.Response.Write(r.Session.Get(r.GetString("k")))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
- r.Session.Remove(r.Get("k"))
+ r.Session.Remove(r.GetString("k"))
})
s.BindHandler("/clear", func(r *ghttp.Request) {
r.Session.Clear()
@@ -68,13 +68,13 @@ func Test_Session_Header(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
- r.Session.Set(r.Get("k"), r.Get("v"))
+ r.Session.Set(r.GetString("k"), r.GetString("v"))
})
s.BindHandler("/get", func(r *ghttp.Request) {
- r.Response.Write(r.Session.Get(r.Get("k")))
+ r.Response.Write(r.Session.Get(r.GetString("k")))
})
s.BindHandler("/remove", func(r *ghttp.Request) {
- r.Session.Remove(r.Get("k"))
+ r.Session.Remove(r.GetString("k"))
})
s.BindHandler("/clear", func(r *ghttp.Request) {
r.Session.Clear()
@@ -121,8 +121,8 @@ func Test_Session_StorageFile(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindHandler("/set", func(r *ghttp.Request) {
- r.Session.Set(r.Get("k"), r.Get("v"))
- r.Response.Write(r.Get("k"), "=", r.Get("v"))
+ r.Session.Set(r.GetString("k"), r.GetString("v"))
+ r.Response.Write(r.GetString("k"), "=", r.GetString("v"))
})
s.SetPort(p)
s.SetDumpRouteMap(false)
@@ -146,7 +146,7 @@ func Test_Session_StorageFile(t *testing.T) {
p := ports.PopRand()
s := g.Server(p)
s.BindHandler("/get", func(r *ghttp.Request) {
- r.Response.Write(r.Session.Get(r.Get("k")))
+ r.Response.Write(r.Session.Get(r.GetString("k")))
})
s.SetPort(p)
s.SetDumpRouteMap(false)
diff --git a/text/gstr/gstr_z_unit_parse_test.go b/text/gstr/gstr_z_unit_parse_test.go
index 16ad9627e..af0fe0aab 100644
--- a/text/gstr/gstr_z_unit_parse_test.go
+++ b/text/gstr/gstr_z_unit_parse_test.go
@@ -18,8 +18,14 @@ import (
func Test_Parse(t *testing.T) {
gtest.Case(t, func() {
+ // name overwrite
+ m, err := gstr.Parse("a=1&a=2")
+ gtest.Assert(err, nil)
+ gtest.Assert(m, g.Map{
+ "a": 2,
+ })
// slice
- m, err := gstr.Parse("a[]=1&a[]=2")
+ m, err = gstr.Parse("a[]=1&a[]=2")
gtest.Assert(err, nil)
gtest.Assert(m, g.Map{
"a": g.Slice{"1", "2"},