Как 2D-массив обрабатывается в запросе HTTP POST

У меня есть HTML-форма, как показано ниже, которая использует 2D-массив для хранения элементов ввода

<form action="/myAction" method="post">
  <input type="text" name="myList[1][NAME]" value="John" />
  <input type="text" name="myList[1][AGE]" value="20" />
  <input type="text" name="myList[2][NAME]" value="Mike" />
  <input type="text" name="myList[2][AGE]" value="30" />
  <input type="text" name="myList[3][NAME]" value="Sam" />
  <input type="text" name="myList[3][AGE]" value="40" />
  <input type="submit" value="submit" />
</form>

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

Спасибо вам за вклад.

РЕДАКТИРОВАТЬ: Похоже, что ниже запрос отправляет 6 параметров в запрос, как я могу отправить только параметр для ниже формы

<form action="/myAction" method="post">
  <input type="text" name="myList[]" value="John" />
  <input type="text" name="myList[]" value="Peter" />
  <input type="text" name="myList[]" value="Mike" />
  <input type="text" name="myList[]" value="Neo" />
  <input type="text" name="myList[]" value="Stella" />
  <input type="text" name="myList[]" value="Eve" />
  <input type="submit" value="submit" />
</form>

Ответ 1

По умолчанию форма будет представлена ​​с типом контента application/x-www-form-urlencoded, поэтому ваши данные будут закодированы в URI с помощью этих правил.

закодированные:

MyList% 5B% 5D = John & MyList% 5B% 5D = Peter & MyList% 5B% 5D = Mike & MyList% 5B% 5D = Neo & MyList% 5B% 5D = Stella & MyList% 5B% 5D = Eve

Раскодированный:

MyList [] = John & MyList [] = Peter & MyList [] = Mike & MyList [] = Neo & MyList [] = Stella & MyList [] = Ева

Если вы хотите отправить только один параметр, вы должны закодировать свои данные на стороне клиента, например. вы можете разделить все значения по запятой.

Вот рабочий пример ( с помощью jQuery):

$('form').submit(function(e) {
    processFormSubmission(this);
});

function processFormSubmission(formElem) {
    var arr = [];
    $(formElem).find(':input').each(function(i) {
        $(this).attr('disabled', 'disabled');    // prevent from submitting
        if( $(this).is(':submit') ) return true; // skip submit input field
        arr.push(this.value);
    });
    $('<input>').attr({type: 'hidden', name: '_data', value: arr.join(',')}).appendTo(formElem);
}

Вышеприведенный код создаст скрытый ввод _data и добавит атрибут disabled к другим полям ввода, поэтому они не будут отправлены на сервер.

_data = Джон, Питер, Майк, NeoStella, Ева

На стороне сервера вы должны декодировать эти данные, например. что-то вроде этого:

// var_dump( $_POST );

if( ! empty( $_POST['_data'] ) {
    $myList = explode(',', $_POST['_data']);
    // var_dump( $myList );
}

Ответ 2

Ответ будет выглядеть следующим образом:

Array
(
    [myList] => Array
        (
            [1] => Array
                (
                    [NAME] => John
                    [AGE] => 20
                )
            [2] => Array
                (
                    [NAME] => Mike
                    [AGE] => 30
                )
            [3] => Array
                (
                    [NAME] => Sam
                    [AGE] => 40
                )
        )
)

edit: чтобы более точно ответить на ваш вопрос, в ответе будет только один параметр, но этот параметр будет массивом. Каждый элемент массива будет самим массивом (обратите внимание, что это массив массивов, а не технически 2D-массив, что не совсем одно и то же).

Как правило, ваша модель хороша, эти данные будут очень легко работать на стороне сервера.

Ответ 3

Это на самом деле довольно полезная функция. Если вы подойдете ближе, вы заметите, что на самом деле это довольно близко к тому, как массивы манипулируют самим PHP.

<input type="text" name="myList[]" value="John" />
<input type="text" name="myList[]" value="Peter" />
<input type="text" name="myList[]" value="Mike" />

Как и в

$myList = [];
$myList[] = "John";
$myList[] = "Peter";
$myList[] = "Mike";

Он был разработан так, что вы можете легко создавать массивы PHP с атрибутом name входов, например

<input type="text" name="myList[user][100505][name]" value="John" />

Было бы так же, если вы определили его в PHP

$_POST['myList']['user']['100505']['name'] = 'John';

Чтобы ваш PHP-модуль заполнил массив $_POST, вам нужно отправить один из двух заголовков Content-Type: application/x-www-form-urlencoded или multipart/form-data; boundary-..., который ваш браузер делает автоматически. Если вы обратите внимание на тело запроса, вы заметите, что параметры определены точно так же, как и имена ваших полей ввода, что означает, что они будут разобраны в одном и том же порядке с одинаковыми значениями.

Рассмотрим следующий пример:

<input type="text" name="myList[]" value="John" />
<input type="text" name="myList[]" value="Peter" />
<input type="text" name="myList[]" value="Mike" />

Это приведет к массиву с 3 элементами, однако

<input type="text" name="myList[1]" value="John" />
<input type="text" name="myList[1]" value="Peter" />
<input type="text" name="myList[1]" value="Mike" />

Это приведет к массиву с только одним элементом, который будет Mike, поскольку параметры анализируются в том порядке, в котором они предусмотрены, и поскольку все они имеют один и тот же ключ, последний будет тем, который вы получите. Кроме того, не обманывайте себя тем, что вы получаете только один элемент, все элементы переносятся по запросу и передаются на сервер, даже если у вас есть 1000 входов, вы все равно получите 1 элемент в своем $_POST['myList'], но все 1000 будут анализироваться.

Вы можете идти вперед и использовать столько уровней, сколько хотите, просто помните, что при этом, если у вас много таких входов и большое количество уровней массивов, это может значительно увеличить размер запроса. Также обратите внимание, что с PHP 7.0 (еще не до конца) количество параметров будет ограничено 1000 для целей безопасности, а именно DoS-атак, которые используют эту слабость и отправляют безумное количество параметров, которые сервер попытается проанализировать, едя ресурсы.

Ответ 4

Использование массивов в параметрах HTTP специфично для реализации на стороне клиента и/или на стороне сервера. В HTTP-протоколе нет массивов (POST и GET включены), и нет даже формата ключа/значения (см. RFC).

Стандарт ключа/значения определяется HTML с помощью <form>. Когда метод POST, тело запроса HTTP содержит "некоторые данные", тип которых application/www-form-urlencoded.

В первом примере HTML будет устанавливать пару ключ/значение для каждого поля input.

Символы [ и ] - это просто случайные байты из представления HTTP-протокола и только часть ключа/имени для HTML.

HTTP-запрос будет выглядеть так:

[...]
Content-Type: application/x-www-form-urlencoded

myList%5B1%5D%5BNAME%5D=John&myList%5B1%5D%5BAGE%5D=20&myList%5B2%5D%5BNAME%5D=Mike&myList%5B2%5D%5BAGE%5D=30&myList%5B3%5D%5BNAME%5D=Sam&myList%5B3%5D%5BAGE%5D=40

Теперь вопрос:

Я хочу знать, сколько параметров будет передано в HTTP-запросе.

В HTTP-запросе всегда есть одна (или ни одна) строка запроса и одно (или none) тело. Таким образом, сам вопрос не имеет смысла. Если это больше о HTML, то ответ будет шесть. Одно поле ввода = одна пара ключ /value = одна конкретная информация. Чтобы иметь более одной информации, вам нужно несколько полей ввода.

Я предполагаю, что вы используете PHP, который анализирует символы [ и ], поэтому из представления PHP вы получите эту структуру:

Array
(
    [myList] => Array
        (
            [1] => Array
                (
                    [NAME] => John
                    [AGE] => 20
                )
            [2] => Array
                (
                    [NAME] => Mike
                    [AGE] => 30
                )
            [3] => Array
                (
                    [NAME] => Sam
                    [AGE] => 40
                )
        )
)

О другом вопросе:

как я могу отправить только параметр для ниже формы

<form action="/myAction" method="post">
  <input type="text" name="myList[]" value="John" />
  <input type="text" name="myList[]" value="Peter" />
  <input type="text" name="myList[]" value="Mike" />
  <input type="text" name="myList[]" value="Neo" />
  <input type="text" name="myList[]" value="Stella" />
  <input type="text" name="myList[]" value="Eve" />
  <input type="submit" value="submit" />
</form>

Шесть входов = шесть значений = шесть ключей/значений. Но PHP предоставит вам один массив, содержащий шесть значений. Или, может быть, вам просто нужен <select>?

Если вы не используете PHP, то это зависит от языка, который вы используете, поэтому, пожалуйста, уточните вопрос.

Ответ 5

Лучшая практика состоит в том, чтобы сделать массив объектами JSON и передать его.