Как 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 и передать его.