一尘不染

如何在Go(Golang)中将表单数据作为地图检索(例如PHP和Ruby)

go

我是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数组键

我独自完成了这项工作,但是…整个表格可能都不是一个好主意(?)

// 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

问题1 :是否有更简单的方法像PHP一样在Golang中将表单数组作为实际地图获取?

问题2 :我应该一个接一个地检索数据(那么麻烦吗,我可能会在某个时候更改Form数据并重新编译…)还是像在第二个示例中所做的那样迭代整个过程。

对不起,我的英语不好…谢谢您!


阅读 202

收藏
2020-07-02

共1个答案

一尘不染

有没有更简单的方法可以像PHP一样在Golang中将表单数组作为实际地图获取?

您可以使用PostFormhttp.Request类型的成员。它是类型url.Values-实际上是(ta-
da)a 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=bazreq.PostFormValue("foo")它将始终返回"bar")。

还要注意,PostForm它将永远不会包含 嵌套结构, 就像您在PHP中使用的那样。由于Go是静态类型的,因此POST表单值将 始终
string(名称)到[]string(值/秒)的映射。

就个人而言,我不会contact[email]在Go应用程序中对POST字段名称使用括号语法()。无论如何,这是一个特定于PHP的构造,并且您已经注意到,Go并不是很好地支持它。

我应该一个接一个地检索数据(尽可能多吗?可能会在某些时候更改Form数据并重新编译…)还是像在第二个示例中所做的那样迭代整个过程。

对此可能没有正确的答案。如果要将POST字段映射到具有静态字段的结构,则必须在某个时候显式映射它们(或用于reflect实现一些神奇的自动映射)。

2020-07-02