doujiao3346 2016-01-17 15:04
浏览 70
已采纳

如何检索表单数据(作为数组)

I'm a PHP Dev. But currently moving to Golang... I'm trying to retrieve data from a Form (Post method):

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

In PHP I would simple use this to get the data:

<?php 
   print_r($_POST["Contact"])
?>
// Output would be something like this:
Array
(
    [Name] => Something
    [Email] => Else
    [Message] => For this message
)

BUT in go... either I get one by one or the whole thing but not the Contact[] Array only such as PHP

I thought about 2 solutions:

1) Get one by one:

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

Note that the map keys are the whole: "Contact[Name]"...

2) Range whole map r.Form and "parse|obtain" those values with Prefix "Contact[" and then replacing "Contact[" and "]" with empty string so I can get the Form array Key only such the PHP Example

I went for this work around by my own but... ranging over the whole form may not be a good idea (?)

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

Both solutions give me the same output... But in the 2nd example I don't necessarily need to know the keys of "Contact[]"

I know... I may just forget about that "Form Array" and use name="Email" on my inputs and retrieve one by one but... I've passing through some scenarios where I use ONE form that contain more than 2 arrays of data and do different things with each one, like ORMs

Question 1: Is there a easier way to get my Form Array as an actual map in Golang like PHP does?

Question 2: 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.

Sorry for my bad English... Thanks in advance!

  • 写回答

3条回答 默认 最新

  • dongqiaozhe5070 2016-01-17 17:20
    关注

    Is there a easier way to get my Form Array as an actual map in Golang like PHP does?

    You can use the PostForm member of the http.Request type. It is of type url.Values -- which is actually (ta-da) a map[string][]string, and you can treat is as such. You'll still need to call req.ParseForm() first, though.

    if err := req.ParseForm(); err != nil {
        // handle error
    }
    
    for key, values := range req.PostForm {
        // [...]
    }
    

    Note that PostForm is a map of lists of strings. That's because in theory, each field could be present multiple times in the POST body. The PostFormValue() method handles this by implicitly returning the first of multiple values (meaning, when your POST body is &foo=bar&foo=baz, then req.PostFormValue("foo") will always return "bar").

    Also note that PostForm will never contain nested structures like you are used from PHP. As Go is statically typed, a POST form value will always be a mapping of string (name) to []string (value/s).

    Personally, I wouldn't use the bracket syntax (contact[email]) for POST field names in Go applications; that's a PHP specific construct, anyway and as you've already noticed, Go does not support it very well.

    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.

    There's probably no correct answer for that. If you are mapping your POST fields to a struct with static fields, you'll have to explicitly map them at some point (or use reflect to implement some magical auto-mapping).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看