如何在查询字符串中传递数组?

时间:2011-06-05 13:03:27

标签: php arrays query-string querystringparameter

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

要清楚,我有一个包含多个值的查询字符串,其中一个值是数组值。我希望将查询字符串值视为数组 - 我不希望数组被展开,以便它与其他查询字符串变量无法区分。

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

修改

基于@Alex的回答,没有标准的方法可以做到这一点,所以我的跟进就是识别的简单方法,我正在阅读的参数是两个数组 PHP Javascript

将多个参数命名为同名是否可以接受,这样我知道它们属于一个数组?例如:

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

或者这是不好的做法?

12 个答案:

答案 0 :(得分:367)

以下是我的想法:

提交多值表单字段,即通过GET / POST变量提交数组,可以通过几种不同的方式完成,因为标准不一定是拼写出来的。

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

  • ?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>

(注意:在这种情况下,将select控件命名为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"

(Angular discussion

请参阅 node.js Wordpress ASP.net

中的示例评论

维护订单 还有一件事需要考虑,如果你需要维护项目的 order (即数组作为有序列表),你实际上只有一个选项,它传递一个分隔的值列表,并且自己明确地将它转换为数组。

答案 1 :(得分:34)

查询字符串包含文本数据,因此没有选项可以爆炸数组,正确编码并以您选择的代表格式传递:

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

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

答案 2 :(得分:17)

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

但是,有一些方法:

  1. 有一种PHP方法,它在URL查询中使用方括号([])。例如,?array_name[]=item&array_name[]=item_2这样的查询虽然记录不完整,但据说可以自动将其转换为数组。资料来源:https://stackoverflow.com/a/9547490/3787376

  2. 对象数据交换格式(例如JSON - official websitePHP documentation)如果有像JSON那样将变量转换为字符串和从字符串转换的方法,也可以使用。
    此外,HTTP get请求还需要一个url-encoder(大多数编程语言都可用)来正确编码字符串数据。

  3. 尽管“方括号方法”很简单且有效,但它仅限于PHP和数组 如果需要其他类型的变量(例如类或在PHP之外的语言中传递查询字符串中的变量),则建议使用JSON方法。

    PHP的JSON方法示例(方法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.
    

答案 3 :(得分:7)

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

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

复选框是我的参数数组。

答案 4 :(得分:4)

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

let data = {
  str: 'abc',
  arr: ['abc', 123]
}

new URLSearchParams(data).toString();
// ?str=abc&arr=abc%2C123, which is the escaped form of ?str=abc&arr=abc,123

答案 5 :(得分:2)

您在问题中提及PHP和Javascript,但在标签中没有。为了将数组传递给MVC.Net动作,我达成了这个问题。

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

答案 6 :(得分:1)

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

答案 7 :(得分:1)

这对我有用:

在链接中,属性具有值->

to =“ / filter / arr?fruits = apple&fruits = banana”

路线可以处理此->

path =“ / filter /:arr”

用于多个阵列

to =“过滤器/ arr?fruits = apple&fruits = banana&vegetables = potato&vegetables = onion”

路线保持不变。

SCREENSHOT

enter image description here

答案 8 :(得分:1)

我使用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

答案 9 :(得分:0)

检查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

?>

答案 10 :(得分:0)

注意查询字符串模块列出了它支持的不同类型的数组编码(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

这表明已经采用了许多解决方案...

答案 11 :(得分:-1)

如果要使用?cars=Saab,Audi。可能需要一些JavaScript才能准备查询字符串。

以下是一个示例:

JavaScript

$('#form-filter').submit(function () {
    event.preventDefault();
    var cars = [];

    $('input[name="select_cars"]:checked').each(function (i) {
      cars.push($(this).val());
    });

    var url = new URL(window.location.href);

    var query_string = url.search;

    var search_params = new URLSearchParams(query_string); 

    if (cars.length == 0) {
       search_params.delete('select_cars');
    }
    else {
       search_params.set('select_cars', cars.join(','));
    }

    url.search = search_params.toString();

    var new_url = url.toString();

    window.location.replace(decodeURIComponent(new_url));
});

PHP


$carsFilter = $_SERVER['select_cars'];

if ($carsFilter) {
  // Converts carsFilter from String to an array.
  $carsFilter = preg_split ("/\,/", $carsFilter);
}

HTML

<label><input name="select_cars" type="checkbox" value="Audi" />Audi</label>
<label><input name="select_cars" type="checkbox" value="Saab" />Saab</label>

在处理包含许多项目的查询字符串数组时,它看起来很整洁。