Как передать массив в строке запроса? - PullRequest
304 голосов
/ 05 июня 2011

Есть ли стандартный способ передачи массива через строку запроса?

Для ясности, у меня есть строка запроса с несколькими значениями, одним из которых будет значение массива. Я хочу, чтобы это значение строки запроса обрабатывалось как массив - я не хочу, чтобы массив разбирался так, чтобы он был неотличим от других переменных строки запроса.

Кроме того, согласно этому пост-ответу , автор предполагает, что поддержка строк в запросах для массивов не определена. Это точно?

EDIT:

Исходя из ответа @ Алекса, стандартного способа сделать это не существует, поэтому мое продолжение - это простой способ распознать , что параметр, который я читаю, является массивом в обоих PHP и Javascript ?

Было бы приемлемо назвать несколько параметров одним и тем же именем, и таким образом я бы знал, что они принадлежат массиву? Пример: * +1021 *

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

Или это будет плохая практика?

Ответы [ 9 ]

376 голосов
/ 03 марта 2012

Вот что я понял:

Отправка полей формы с несколькими значениями, т. Е. Отправка массивов с помощью переменных 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[] для нескольких значений действительно плохо документировано,Я не вижу упоминаний об этом в разделе о многозначных ключах в Строка запроса - Википедия или в W3C документах , касающихся многократных вводов.


ОБНОВЛЕНИЕ

Как отметили комментаторы, это очень сильно зависит от фреймворка.Некоторые примеры:

Строка запроса:

?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 обсуждение )

См. Комментарии к примерам в node.js , Wordpress , ASP.net


Поддержание порядка: Еще одна вещь, на которую следует обратить внимание: если вам нужно поддерживать порядок ваших товаров(т.е. массив как упорядоченный список), у вас действительно есть только одна опция, которая передает разделенный список значений и явно конвертирует его в массив самостоятельно.

36 голосов
/ 05 июня 2011

Строка запроса содержит текстовые данные, поэтому нет другого выбора, кроме как взорвать массив, правильно его кодировать и передать в выбранном формате представления:

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

и затем расшифруйте его в коде на стороне сервера.

19 голосов
/ 05 июня 2011

Я не думаю, что есть стандарт.
Каждая веб-среда предоставляет свой «стандарт» для таких вещей.Кроме того, URL-адрес обычно слишком короткий для чего-либо (ограничение 256 байтов в некоторых браузерах).Конечно, более длинные массивы / данные могут быть отправлены с запросами POST.

Однако есть несколько методов:

  1. Есть способ PHP, которыйиспользует квадратные скобки ([, ]) в запросах URL.Например, такой запрос, как ?array_name[]=item&array_name[]=item_2, как говорят, работает, хотя и плохо документирован, а PHP автоматически преобразует его в массив.Источник: https://stackoverflow.com/a/9547490/3787376

  2. Форматы обмена объектными данными (например, JSON - официальный сайт , PHP-документация ) также могут использоваться, если у них есть методыпреобразование переменных в и из строк, как это делает JSON.
    Кроме того, для запросов HTTP get для правильного кодирования строковых данных требуется URL-кодировщик (доступен для большинства языков программирования).

Хотя «метод квадратных скобок» прост и работает, он ограничен 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.
7 голосов
/ 08 января 2013

Мне кажется, это будет полезно для тех, кто ищет передачу массива в строке запроса сервлету. Я протестировал приведенную ниже строку запроса и смог получить значения массива с помощью req.getgetParameterValues ​​(); метод. Ниже приведена строка запроса, которую я передал через браузер.

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

Чекбокс - это мой массив параметров здесь.

2 голосов
/ 24 марта 2015

Вы упоминаете PHP и Javascript в своем вопросе, но не в тегах.Я пришел к этому вопросу с намерением передать массив в действие MVC.Net.

Я нашел ответ на свой вопрос здесь : ожидаемый формат - это тот, который вы предложили в своем вопросес несколькими параметрами, имеющими одно и то же имя.

1 голос
/ 05 июня 2011

Вы можете использовать http_build_query для генерации строки запроса в кодировке URL из массива в PHP. Хотя результирующая строка запроса будет расширена, вы можете выбрать уникальный разделитель, который вы хотите использовать в качестве параметра метода http_build_query, поэтому, когда дело доходит до декодирования, вы можете проверить, какой разделитель использовался. Если бы он был уникальным, то это была бы строка запроса массива, иначе это были бы обычные строки запроса.

0 голосов
/ 11 марта 2019

Если вы хотите использовать ?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>

Это выглядит аккуратно при работе с массивом строк запроса из многих элементов.

0 голосов
/ 30 ноября 2018

Это работает для меня:

В ссылке, атрибут имеет значение:

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

Маршрут может обрабатывать это:

path="/filter/:arr"

Для нескольких массивов:

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

Маршрут остается прежним.

СКРИНШОТ

enter image description here

0 голосов
/ 03 марта 2012

Проверьте функцию 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

?>
...