<!-- 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 print_r($_POST["Contact"]) ?> // Output would be something like this: Array ( [Name] => Something [Email] => Else [Message] => For this message )
但是…要么我一个接一个,要么全部,但不是像PHP这样的Contact []数组
我想到了两个解决方案:
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]
请注意,地图键是整体:“联系[姓名]”…
2)范围整个映射r.Form并用前缀“解析”这些值
“联系[”然后用空字符串替换“Contact [”和“]”
所以我只能获得Form数组Key这样的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]
两种解决方案都给我相同的输出…但在第二个例子中,我不一定需要知道“联系人[]”的键.
我知道……我可能会忘记那个“Form Array”并在我的输入上使用name =“Email”并逐个检索但是…我已经通过一些场景我使用一个包含多个表单的表单2个数据数组,每个数据都有不同的东西,比如ORM
问题1:有没有更简单的方法将我的表单数组作为Golang中的实际地图,就像PHP一样?
问题2:我应该逐个检索数据(单调乏味,我可能会在某个时候更改表单数据并重新编译……)或者按照我在第二个示例中所做的那样迭代整个数据.
对不起我的英语不好…提前致谢!
解决方法
Is there a easier way to get my Form Array as an actual map in Golang like PHP does?
您可以使用http.Request类型的PostForm成员.它是url.Values
型 – 实际上是(ta-da)一个map [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”).
另请注意,PostForm永远不会包含像PHP中使用的嵌套结构.由于Go是静态类型的,因此POST表单值将始终是字符串(名称)到[]字符串(值/ s)的映射.
就个人而言,我不会在Go应用程序中使用支持语法(联系[email])来获取POST字段名称;这是一个PHP特定的构造,无论如何,正如你已经注意到的,Go并不支持它.
Should I retrieve the data one by one (Tedious as much and I may change the Form data at some point and recompile…) or iterate the whole thing as I’ve done in the 2nd example.
对此可能没有正确的答案.如果要将POST字段映射到具有静态字段的结构,则必须在某个时刻显式映射它们(或使用reflect
实现一些神奇的自动映射).