我是PHP开发人员。但是目前正在转向Golang …我正在尝试从Form(Post方法)中检索数据:
<!-- A really SIMPLE form --> <form class="" action="/Contact" method="post"> <input type="text" name="Contact[Name]" value="Something"> <input type="text" name="Contact[Email]" value="Else"> <textarea name="Contact[Message]">For this message</textarea> <button type="submit">Submit</button> </form>
在PHP中,我将简单地使用它来获取数据:
<?php print_r($_POST["Contact"]) ?> // Output would be something like this: Array ( [Name] => Something [Email] => Else [Message] => For this message )
但是…我要么一一得到,要么整个都得到,但没有诸如PHP之类的Contact []数组
我考虑了2个解决方案:
1)一一获得:
// r := *http.Request err := r.ParseForm() if err != nil { w.Write([]byte(err.Error())) return } contact := make(map[string]string) contact["Name"] = r.PostFormValue("Contact[Name]") contact["Email"] = r.PostFormValue("Contact[Email]") contact["Message"] = r.PostFormValue("Contact[Message]") fmt.Println(contact) // Output map[Name:Something Email:Else Message:For this Message]
请注意,映射键是整体:“ Contact [Name]” …
2)排列整个地图,r.Form并用前缀“ Contact [”“解析”获得这些值,然后用空字符串替换“ Contact [”和“]”,这样我只能得到PHP例子中的Form数组键
r.Form
我独自完成了这项工作,但是…整个表格可能都不是一个好主意(?)
// ContactPost process the form sent by the user func ContactPost(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { err := r.ParseForm() if err != nil { w.Write([]byte(err.Error())) return } contact := make(map[string]string) for i := range r.Form { if strings.HasPrefix(i, "Contact[") { rp := strings.NewReplacer("Contact[", "", "]", "") contact[rp.Replace(i)] = r.Form.Get(i) } } w.Write([]byte(fmt.Sprint(contact))) } //Output map[Name:Something Email:Else Message:For this Message]
两种解决方案都给我相同的输出…但是在第二个示例中,我不一定需要知道“ Contact []”的键
我知道…我可能只是忘了那个“表单数组”,name="Email"而是在输入中使用并逐个检索,但是…我经历了一些情况,在这种情况下,我使用一个包含两个以上数据数组的表单。彼此做不同的事情,例如ORM
name="Email"
问题1 :是否有更简单的方法像PHP一样在Golang中将表单数组作为实际地图获取?
问题2 :我应该一个接一个地检索数据(那么麻烦吗,我可能会在某个时候更改Form数据并重新编译…)还是像在第二个示例中所做的那样迭代整个过程。
对不起,我的英语不好…谢谢您!
有没有更简单的方法可以像PHP一样在Golang中将表单数组作为实际地图获取?
您可以使用PostForm该http.Request类型的成员。它是类型url.Values-实际上是(ta- da)a map[string][]string,您可以这样处理。不过,您仍然需要先致电req.ParseForm()。
PostForm
http.Request
url.Values
map[string][]string
req.ParseForm()
if err := req.ParseForm(); err != nil { // handle error } for key, values := range req.PostForm { // [...] }
请注意,这PostForm是 字符串列表的 映射 。这是因为从理论上讲,每个字段都可以在POST正文中多次出现。该PostFormValue()方法通过隐式返回多个值中的 第一个 值来处理此问题(意味着,当您的POST正文为时&foo=bar&foo=baz,req.PostFormValue("foo")它将始终返回"bar")。
PostFormValue()
&foo=bar&foo=baz
req.PostFormValue("foo")
"bar"
还要注意,PostForm它将永远不会包含 嵌套结构, 就像您在PHP中使用的那样。由于Go是静态类型的,因此POST表单值将 始终 是string(名称)到[]string(值/秒)的映射。
string
[]string
就个人而言,我不会contact[email]在Go应用程序中对POST字段名称使用括号语法()。无论如何,这是一个特定于PHP的构造,并且您已经注意到,Go并不是很好地支持它。
contact[email]
我应该一个接一个地检索数据(尽可能多吗?可能会在某些时候更改Form数据并重新编译…)还是像在第二个示例中所做的那样迭代整个过程。
对此可能没有正确的答案。如果要将POST字段映射到具有静态字段的结构,则必须在某个时候显式映射它们(或用于reflect实现一些神奇的自动映射)。
reflect