【问题标题】:How to pass an array within a query string?如何在查询字符串中传递数组?
【发布时间】:2016-02-23 01:43:03
【问题描述】:

是否有通过查询字符串传递数组的标准方法?

明确地说,我有一个包含多个值的查询字符串,其中一个是数组值。我希望将该查询字符串值视为一个数组 - 我不希望该数组被分解,使其与其他查询字符串变量无法区分。

另外,根据post answer,作者建议未定义对数组的查询字符串支持。这准确吗?

编辑:

根据@Alex 的回答,没有标准的方法可以做到这一点,所以我的后续行动是识别我正在读取的参数是一个数组的简单方法PHPJavascript

是否可以将多个参数命名为相同的名称,这样我就可以知道它们属于一个数组?示例:

?myarray=value1&myarray=value2&myarray=value3...

或者这是一个不好的做法?

【问题讨论】:

  • 你用的是什么框架?一些框架具有帮助将数组传递给查询字符串的方法。
  • @keyboardP- PHP 和 Javascript,取决于用例
  • 既然可以这样做,为什么还要这样做:?myarray=value1,value2,value3
  • @seroids:如果他必须传递逗号、问号、等号和不可打印字符怎么办?

标签: php arrays query-string querystringparameter


【解决方案1】:

查询字符串带有文本数据,因此别无选择,只能分解数组,正确编码并以您选择的表示格式传递:

p1=value1&pN=valueN...
data=[value1,...,valueN]
data={p1:value1,...,pN:valueN}

然后在您的服务器端代码中对其进行解码。

【讨论】:

  • 好的,感谢您的澄清。您能看到我修改后的问题吗?是否有必要为键执行 p1...pn,或者我可以将多个键命名为“p”,这样我就知道它们都属于同一个数组?
  • 可以使用同名; stackoverflow.com/questions/2203430/… 或只是 p=aa,bb,cc 这是 Serodis 评论的最明显的方式。
  • JSON.stringifyJSON.parse非常有用!
  • 一种简单而常见的表示格式是 JSON,在 PHP 中使用json_encode,然后在另一页上使用rawurlencodejson_decode
【解决方案2】:

我认为没有标准。
每个网络环境都为这些事情提供了自己的“标准”。此外,该 url 通常对于任何东西都太短(某些浏览器限制为 256 字节)。当然更长的数组/数据可以通过 POST 请求发送。

不过,有一些方法:

  1. 有一种 PHP 方式,它在 URL 查询中使用方括号 ([,])。例如,?array_name[]=item&array_name[]=item_2 之类的查询据说可以工作,尽管文档记录很差,PHP 会自动将其转换为数组。来源:https://stackoverflow.com/a/9547490/3787376

  2. 如果对象数据交换格式(例如 JSON - official websitePHP documentation)具有像 JSON 那样在字符串之间转换变量的方法,也可以使用它们。
    HTTP get 请求还需要一个 url 编码器(适用于大多数编程语言)才能正确编码字符串数据。

“方括号法”虽然简单有效,但仅限于 PHP 和数组。
如果需要其他类型的变量,例如类或在非 PHP 语言的查询字符串中传递变量,建议使用 JSON 方法。

JSON方法的PHP示例(方法2):

$myarray = array(2, 46, 34, "dfg");
$serialized = json_encode($myarray)
$data = 'myarray=' . rawurlencode($serialized);
// Send to page via cURL, header() or other service.

接收页面代码(PHP):

$myarray = json_decode($_GET["myarray"]); // Or $_POST["myarray"] if a post request.

【讨论】:

  • Express.js 还支持方括号表示法,在 4.13.4 上测试。
  • 如果您要使用json_encode,最好在将字符串作为get param传递时对字符串进行base64_encode和解码
【解决方案3】:

您可以使用http_build_query 从 PHP 中的数组生成 URL 编码的查询字符串。虽然生成的查询字符串将被扩展,但您可以决定您想要的唯一分隔符作为http_build_query 方法的参数,因此在解码时,您可以检查使用的分隔符。如果它是您选择的唯一一个,那么它将是数组查询字符串,否则它将是正常的查询字符串。

【讨论】:

    【解决方案4】:

    这是我想出来的:

    提交多值表单字段,即通过 GET/POST vars 提交数组,可以通过几种不同的方式完成,因为标准不一定要详细说明。

    发送多值字段或数组的三种可能方式是:

    • ?cars[]=Saab&cars[]=Audi (最好的方法——PHP 将它读入一个数组)
    • ?cars=Saab&cars=Audi (不好的方式 - PHP 只会注册最后一个值)
    • ?cars=Saab,Audi (没试过)

    表单示例

    在表单上,​​多值字段可以采用选择框设置为多个的形式:

    <form> 
        <select multiple="multiple" name="cars[]"> 
            <option>Volvo</option> 
            <option>Saab</option> 
            <option>Mercedes</option> 
        </select>
    </form>
    

    (注意:在这种情况下,将选择控件命名为 some_name[] 很重要,这样生成的请求变量将被 PHP 注册为数组)

    ...或作为多个具有相同名称的隐藏字段

    <input type="hidden" name="cars[]" value="Volvo">
    <input type="hidden" name="cars[]" value="Saab">
    <input type="hidden" name="cars[]" value="Mercedes">
    

    注意:field[] 用于多个值的文档确实很少。我在Query string - Wikipedia 中关于多值键的部分或在处理多选输入的W3C docs 中没有看到任何提及。


    更新

    正如评论者所指出的,这在很大程度上是特定于框架的。一些例子:

    查询字符串:

    ?list_a=1&list_a=2&list_a=3&list_b[]=1&list_b[]=2&list_b[]=3&list_c=1,2,3
    

    导轨:

    "list_a": "3", 
    "list_b":[
        "1",
        "2",
        "3"
      ], 
    "list_c": "1,2,3"
    

    角度:

     "list_a": [
        "1",
        "2",
        "3"
      ],
      "list_b[]": [
        "1",
        "2",
        "3"
      ],
      "list_c": "1,2,3"
    

    (角度discussion

    node.jsWordpressASP.net

    中的示例请参见 cmets

    维护秩序: 要考虑的另一件事是,如果您需要维护项目的 order(即数组作为有序列表),您实际上只有一个选项,即传递一个分隔的值列表,并且自己显式地将其转换为数组。

    【讨论】:

    • 我认为此功能未在 Wiki 或 W3C 等一般资源中记录的原因是 Web 框架通常不支持此功能。 PHP 和我认为 Rails 会自动将多个“key[]”查询参数转换为一个数组。其他人没有。
    • nodejs 查询字符串模块使用?cars=Saab&amp;cars=Audi 形式
    • 在 express (node.js) 中,?cars=Saab&amp;cars=Audi?cars[]=Saab&amp;cars[]=Audi 都变成了数组。但是,?cars=Saab 以字符串形式结束,而 ?cars[]=Saab 是具有单个元素的数组。
    • 您可以使用这种方法设置密钥吗?那么多维数组呢?
    • ASP.NET MVC 似乎无法读取?cars[]=Saab&amp;cars[]=Audi 格式,要么没有方括号,要么方括号需要索引/
    【解决方案5】:

    检查parse_string函数http://php.net/manual/en/function.parse-str.php

    它将返回查询字符串中的所有变量,包括数组。

    来自 php.net 的示例:

    <?php
    $str = "first=value&arr[]=foo+bar&arr[]=baz";
    parse_str($str);
    echo $first;  // value
    echo $arr[0]; // foo bar
    echo $arr[1]; // baz
    
    parse_str($str, $output);
    echo $output['first'];  // value
    echo $output['arr'][0]; // foo bar
    echo $output['arr'][1]; // baz
    
    ?>
    

    【讨论】:

      【解决方案6】:

      我觉得这对于正在寻找将查询字符串中的数组传递给 servlet 的人会有所帮助。我在下面的查询字符串中进行了测试,并且能够使用 req.getgetParameterValues(); 获取数组值;方法。下面是我通过浏览器传递的查询字符串。

        http://localhost:8080/ServletsTutorials/*.html? 
        myname=abc&initial=xyz&checkbox=a&checkbox=b
      

      checkbox 是我这里的参数数组。

      【讨论】:

        【解决方案7】:

        您在问题中提到了 PHP 和 Javascript,但在标签中没有提到。我遇到这个问题的目的是将数组传递给 MVC.Net 操作。

        我找到了我的问题here 的答案:预期格式是您在问题中提出的格式,多个参数具有相同的名称。

        【讨论】:

        • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
        • @Andrew 这不仅仅是一个链接的答案。 “预期的格式是您在问题中提出的格式,多个参数具有相同的名称。”
        【解决方案8】:

        这对我有用:

        在链接中,to 属性有值:

        to="/filter/arr?fruits=apple&fruits=banana"
        

        路由可以处理这个:

        path="/filter/:arr"
        

        对于多个数组:

        to="filter/arr?fruits=apple&fruits=banana&vegetables=potato&vegetables=onion"
        

        路线保持不变。

        屏幕截图

        更新: 为了实现这种字符串结构,query-string是最好的封装。

        例如:

        import { stringify, parse } from 'query-string';
        
        const queryParams={
           fruits:['apple','banana'],
           vegetables:['potato','onion']
        }
        //arrayFormat can be bracket or comma 
        stringify(queryParams, { arrayFormat: 'bracket' });
        

        【讨论】:

          【解决方案9】:

          我使用 React 和 Rails。我做到了:

          js

            let params = {
              filter_array: ['A', 'B', 'C']
            }
          
            ...
          
            //transform params in URI
          
            Object.keys(params).map(key => {
              if (Array.isArray(params[key])) {
                return params[key].map((value) => `${key}[]=${value}`).join('&')
              }
            }
            //filter_array[]=A&filter_array[]=B&filter_array[]=C
          

          【讨论】:

            【解决方案10】:

            虽然 URL 部分没有标准,但 JavaScript 有一个标准。如果您将包含数组的对象传递给URLSearchParams,并在其上调用toString(),它会将其转换为逗号分隔的项目列表:

            let data = {
              str: 'abc',
              arr: ['abc', 123]
            }
            
            new URLSearchParams(data).toString();
            // ?str=abc&arr=abc,123 (with escaped comma characters)
            

            【讨论】:

            • 准确地说它会产生转义结果:"str=abc&amp;arr=abc%2C123"
            • 确实,我会更新代码以显示它。重点还是一样的,就是 js 的“标准”是在数组中使用逗号。
            • arr=abc&amp;arra=123 相比,逗号分隔是否更好/兼容?
            • @DimitriKopriwa 猜你的意思是arr=abc&amp;arr=123。我想说 JS 做的稍微好一点,因为它使用的字符更少,前端代码会更简单,并且会保持项目的顺序,但只要使用你的后端框架(django、PHP、laravel 等) ) 支持。如果我自己实现解析,我可能会使用逗号分隔的方法。
            • URLSearchParams 只接受字符串参数,不接受数组!任何非字符串都只是通过正常的 toString 行为自动转换为字符串。 JavaScript 通过用逗号连接条目将数组转换为字符串这一事实不应被视为 JavaScript 在 URL 中编码数组数据的标准方式。这就是 JavaScript 跨语言将数组转换为字符串的简单方式。
            【解决方案11】:

            请注意,查询字符串模块列出了它支持的不同类型的数组编码 (https://www.npmjs.com/package/query-string):

            例如 {foo: ['1', '2', '3']} 可以编码为:

            'foo[]=1&foo[]=2&foo[]=3'
            'foo[0]=1&foo[1]=2&foo[3]=3'
            'foo=1,2,3'
            'foo=1&foo=2&foo=3'
            // Any custom separator can be used:
            'foo=1|2|3'
            // ... and more custom formats
            

            这表明有很多解决方案被采用...

            【讨论】:

              猜你喜欢
              • 2013-04-02
              • 2012-07-03
              • 2014-04-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多