我是一名 PHP 开发人员。但目前正在转向 Golang ……我正在尝试从表单(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]”…
- Range whole map
r.Form
并“解析|获取”前缀为“Contact[”的值,然后用空字符串替换“Contact[”和“]”,这样我就可以获得表单数组键PHP 示例
我自己完成了这项工作,但是……遍历整个表格可能不是一个好主意(?)
// 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"
并一个一个地检索但是……我已经经历了一些场景,我使用一个包含超过 2 个数据数组,并对每个数组做不同的事情,比如 ORM
问题 1 :有没有更简单的方法让我的表单数组像 PHP 一样在 Golang 中作为实际地图?
问题 2 :我应该一个一个地检索数据(同样乏味,我可能会在某个时候更改表单数据并重新编译……)还是像我在第二个示例中所做的那样迭代整个过程。
抱歉我的英语不好…提前致谢!
原文由 David Lavieri 发布,翻译遵循 CC BY-SA 4.0 许可协议
您可以使用
PostForm
http.Request
类型的成员。它是类型url.Values
实际上是 (ta-da) amap[string][]string
,你可以这样对待。不过,您仍然需要先致电req.ParseForm()
。请注意
PostForm
是 字符串列表的 映射。这是因为理论上,每个字段都可以在 POST 正文中出现多次。 ThePostFormValue()
method handles this by implicitly returning the first of multiple values (meaning, when your POST body is&foo=bar&foo=baz
, thenreq.PostFormValue("foo")
will always return"bar"
)。另请注意
PostForm
永远不会包含 嵌套结构,就像您在 PHP 中使用的那样。由于 Go 是静态类型的,POST 表单值将 始终 是string
(名称)到[]string
(值/s)的映射。就个人而言,我不会在 Go 应用程序中对 POST 字段名称使用方括号语法(
contact[email]
);这是一个特定于 PHP 的构造,无论如何,正如您已经注意到的那样,Go 对它的支持不是很好。可能没有正确答案。如果您将 POST 字段映射到具有静态字段的结构,则必须在某些时候显式映射它们(或使用
reflect
来实现一些神奇的自动映射)。