Как правильно в php принять массив из formData js?
Добрый день!
Столкнулся с такой проблемой. Не могу принять массив в php, который закидываю в formData.
Массив формирую вот так:
//объявляем массив для сохранения значений const messagesValue = []; //функция добавления объекта(пары ключ значение) в массив function addDataPair(key,value){ let pair = {key: key, value: value}; messagesValue.push(pair); } //перебираем массив сообщений messages.forEach(element => { if (element.classList.contains('AB__chat__inner__center__bot')) { addDataPair("Оператор: ", (element.children[0]).textContent); } else if (element.classList.contains('AB__chat__inner__center__people')) { addDataPair("Вы: ", (element.children[0]).textContent); } }); |
//объявляем массив для сохранения значений const messagesValue = []; //функция добавления объекта(пары ключ значение) в массив function addDataPair(key,value){ let pair = {key: key, value: value}; messagesValue.push(pair); } //перебираем массив сообщений messages.forEach(element => { if (element.classList.contains('AB__chat__inner__center__bot')) { addDataPair("Оператор: ", (element.children[0]).textContent); } else if (element.classList.contains('AB__chat__inner__center__people')) { addDataPair("Вы: ", (element.children[0]).textContent); } });
дальше осуществляю отправку...
......... .onSuccess((event) => { let formData = new FormData(); formData.append('messages', JSON.stringify(array)); console.log(...formData); let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { // console.log('Отправлено'); } } } xhr.open('POST', 'mail.php', true); xhr.send(formData); event.target.reset(); }); ............ |
......... .onSuccess((event) => { let formData = new FormData(); formData.append('messages', JSON.stringify(array)); console.log(...formData); let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { // console.log('Отправлено'); } } } xhr.open('POST', 'mail.php', true); xhr.send(formData); event.target.reset(); }); ............
в php пытаюсь принять так:
..... $data = json_decode($_POST['messages']); ... |
..... $data = json_decode($_POST['messages']); ...
Но данные не принимаются и не парсятся ни в какую... Если в форм дату закидываю event.target, то все работает....как только передаю массив -- по нулям.
Заранее спасибо за любую помощь.
Дополнительно:
а разве формдата может принимать целый json в аппенд? 0_О
['messages', '[{"key":"Вы: ","value":"ооалотп"},{"key":"Оператор…value":"рп"}...................]']... то есть 0 это ключ который установил, а 1 - это строка json..
На тот ли скрипт сервера отправляет? (правильный путь до php?)
Если открыть строчку в сети этого запроса. Ваш json появился в "Полезной нагрузке" запроса?
Всем спасибо... Натолкнули на мысль, что я допускал одну очень простую ошибку..... Итак, по логике работы данного кода, помимо массива я передавал еще и почту, на которую нужно отправить данные. Соответсвенно, убирая event.target из formData я конечно терял введенное значение и массив то может и принимался, только куда его и что с ним делать....код не знал... по итогу, решение такое:
Во первых решил остаться все-таки на formData, т.к. возможно в скором времени понадобиться пересылка файлов.
Во вторых. просто собрал массив, а не массив объектов, как было до этого.
как-то так
//объявляем массив для сохранения значений const messagesValue = []; //перебираем массив сообщений messages.forEach(element => { if (element.classList.contains('AB__chat__inner__center__bot')) { messagesValue.push("Оператор: " + (element.children[0]).textContent); } else if (element.classList.contains('AB__chat__inner__center__people')) { messagesValue.push('Вы: ' + (element.children[0]).textContent); } }); |
//объявляем массив для сохранения значений const messagesValue = []; //перебираем массив сообщений messages.forEach(element => { if (element.classList.contains('AB__chat__inner__center__bot')) { messagesValue.push("Оператор: " + (element.children[0]).textContent); } else if (element.classList.contains('AB__chat__inner__center__people')) { messagesValue.push('Вы: ' + (element.children[0]).textContent); } });
в третьих. formdata формирую следующим образом:
validation .onSuccess((event) => { let formData = new FormData(); formData.append('key1', JSON.stringify(array)); formData.append('key2', input); let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { alert(''); } } } xhr.open('POST', 'mail.php', true); xhr.send(formData); event.target.reset(); }); } |
validation .onSuccess((event) => { let formData = new FormData(); formData.append('key1', JSON.stringify(array)); formData.append('key2', input); let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { alert(''); } } } xhr.open('POST', 'mail.php', true); xhr.send(formData); event.target.reset(); }); }
ну и наконец, принимаю это дело так
if (isset($_POST['key1'])) { $array = json_decode($_POST['key1']); .............. $inputValue = $_POST["key2"]; |
if (isset($_POST['key1'])) { $array = json_decode($_POST['key1']); .............. $inputValue = $_POST["key2"];
По итогу все заработало. Невнимательность прежде всего.... всем спасибо, и будьте внимательны))
Ответы:
Если ты отправляешь не файлы, то нет смысла использовать FormData, просто отправляй JSON-строку напрямую.
let xhr = new XMLHttpRequest(); xhr.open('POST', 'mail.php', true); xhr.setRequestHeader('Content-Type', 'text/plain'); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { console.log('Ответ сервера:', xhr.responseText); } } } console.log('Отправляем:', array); xhr.send(JSON.stringify(array)); |
let xhr = new XMLHttpRequest(); xhr.open('POST', 'mail.php', true); xhr.setRequestHeader('Content-Type', 'text/plain'); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { console.log('Ответ сервера:', xhr.responseText); } } } console.log('Отправляем:', array); xhr.send(JSON.stringify(array));
На стороне PHP принимаешь данные так:
<?php header('Content-Type: text/plain'); $array = json_decode(file_get_contents('php://input'), true); echo 'Из браузера получены данные: ' . print_r($array, true); |
<?php header('Content-Type: text/plain'); $array = json_decode(file_get_contents('php://input'), true); echo 'Из браузера получены данные: ' . print_r($array, true);
- А зачем text/plain, когда json это application/json?
- Rise, при POST запросах из браузера на сервер бывают 2 типа запросов: простые и сложные.
Простые запросы это запросы с кодировками:
1) application/x-www-form-urlencoded
2) multipart/form-data
3) text/plainВсе остальные кодировки делают запрос сложными. При сложных запросах браузер перед отправкой запроса всегда делает так называемый предзапрос, в консоли такие запросы можно увидеть с пометкой OPTION и так уж выходит, если ты пропишешь application/json оно конечно будет работать, но браузер будет вместо одного запроса отправлять 2 запроса: сначала предзапрос (чтобы проверить соответствие CORS) и только потом сам запрос.
P. S. Это касается только запросов на другие домены, если запрос на свой собственный домен идет, то можешь смело ставить application/json, предзапросов не будет, но если вдруг обработчик у тебя на другом сайте, лучше использовать text/plain - собственно это универсальное решение, проще сразу изначально везде так делать.
https://learn.javascript.ru/fetch-crossorigin#nepr....
- zkrvndm, по вашей ссылке написано что предзапрос кешируется заголовком Access-Control-Max-Age, поэтому он не выполняется каждый запрос.
А если отойти от PHP-сервера, в котором нет из коробки автопарсинга json-запросов, то почему вы думаете что его не может быть в других серверах, технологиях, языках?
- Rise, кешируется, я не спорю, но касается это вроде бы только GET запросов, а при POST запросах кеширование по умолчанию не используется, более того я также указал, что это все касается только запросов на другие домены, при работе со своим сервером никаких предзапросов не будет, но тем не менее я часто на крупных портал вижу, что стандартной практикой считается отсылать JSON в кодировке text/plain - прям очень часто вижу такую практику.
Также насчет кеша, замечу, что если мы игнорируем кеш при помощи добавления в адрес временной метки, ничего там кешироватся не будет и OPTIOS запросы будут всегда. Это опять же стандартная практика (насчет добавления временной метки для игнорирования кеша). Все же если мы отправляем запрос с данными, нам как правило не нужен ответ из кеша, а нужен актуальный ответ.
К счастью, в данном вопросе стоит тег PHP поэтому и мой ответ касается исключительно PHP.
- zkrvndm, причем здесь GET или POST, когда OPTIONS это другой метод запроса. Это отдельный запрос, вы же сами писали что их два: предзапрос и сам запрос. Вот этот предзапрос, выполненный методом OPTIONS и кешируется, если вы не поняли, а не сам запрос.
Временные метки используются, чтобы функции или дизайн сайта обновлять в какой-нибудь CMS, например, script.js?ver=1234567890 или style.css?ver=1234567890 соответственно, не более.
- Rise, не кешируется, если отправляем POST.
- Rise, вот, смотри:
Я отправил 3 POST запроса на один и тот же адрес и все три раза сначала шел предзапрос OPTIONS - не кешируется там ничего. Вместо того, чтобы вот так вот грузить сервер в 2 раза чаше, проще использовать text/plain! Такой запрос будет идти в 2 раза быстрее, за счет отсутствия предзапроса.
- zkrvndm, так кешированные запросы тоже отображаются в консоле, просто там указано disk cache, но физически они на сервер не идут, ответы сервера хранятся в браузере и извлекаются на запрос, в этом и суть кэша.
- Rise, по поводу временных меток ты не прав, это единственный гарантированный способ сделать запрос без кеша, поэтому такой подходи используется широко и везде.
- Rise, нет, обрати внимание на черепашку, черепашки не бывает при использовании дискового кеша. Просто поверь на слово, texp/plain оптимальный вариант, особенно когда надо отправить и принять много данных. Когда речь идет о тысячах и тысячах запросов с секунду, каждый лишние 50 мс. на счету. Не наш случай конечно, но тем не менее, на крупных портал это обычная практика так засылать данные на бэкенд.
- zkrvndm, то что у вас что-то не кешируется значит неправильно что-то делаете, как и здесь. А про "единственный" способ могу посоветовать вам ознакомиться с fetch-опцией cache.
- Rise, которая работает только с fetch, ага. Вы что, думайте jQuery.ajax при cache: false зря штамп в адрес добавляет? Нет, эту либу умные люди писали, именно так максимально надежное игнорирование кеша получается.
Что я неправильно делаю? Все я правильно делаю. Мне доводилось писать приложения которые за секунду шлют тысячи и тысячи запросов и проблема с тормозами из-за OPTIONS запросов это первое с чем я столкнулся и что мне пришлось решать.
- zkrvndm, покажите пример php посмотрим что неправильно.
- Rise, убедись сам:
xhr = new XMLHttpRequest(); xhr.open('POST', 'https://nadim.work/test.php', true); xhr.setRequestHeader('Content-Type', 'aplication/json'); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { console.log('Ответ сервера:', xhr.responseText); } } } xhr.send('{}');
xhr = new XMLHttpRequest(); xhr.open('POST', 'https://nadim.work/test.php', true); xhr.setRequestHeader('Content-Type', 'aplication/json'); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { console.log('Ответ сервера:', xhr.responseText); } } } xhr.send('{}');
- zkrvndm, это не php это js.
- Rise, да, речь про браузер же. OPTIONS запросы делает браузер с целью проверки на соответствие CORS. А ты чего ожидал?
- Rise, я понял про что вы. Да, это по идее будет работать если адрес запроса все время фиксированный, но лично у меня так никогда не бывает, всегда все запросы с временным штампом делаю.
- А мне надо в том же файле принять в PHP информацию из JS (localStorage). Неделю вот пытался делать и как тут сказано и иначе, всегда пустота лишь на стороне PHP.
Пока мне помог лишь такой вариант:<script> var js; var obj = {} for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i); obj[key] = localStorage.getItem(key); } js = JSON.stringify(obj); </script>
<script> var js; var obj = {} for (var i = 0; i < localStorage.length; i++) { var key = localStorage.key(i); obj[key] = localStorage.getItem(key); } js = JSON.stringify(obj); </script>
И чуть ниже в файле этом же:
<?php if (isset($_POST['obj'])) { $mainData = json_decode($_POST['obj'], true); foreach ($mainData as $k => $v){ echo $k . " === " . ($v + 232) . PHP_EOL; } } else { echo "<script type='text/javascript'>"; echo "document.write('<form method='post' id='f'>');"; echo "document.write('<input type='hidden' name='obj' value = '' + js + ''</p>');"; echo "document.write('</form>');"; echo "document.getElementById('f').submit()"; echo "</script>"; }
<?php if (isset($_POST['obj'])) { $mainData = json_decode($_POST['obj'], true); foreach ($mainData as $k => $v){ echo $k . " === " . ($v + 232) . PHP_EOL; } } else { echo "<script type='text/javascript'>"; echo "document.write('<form method='post' id='f'>');"; echo "document.write('<input type='hidden' name='obj' value = '' + js + ''</p>');"; echo "document.write('</form>');"; echo "document.getElementById('f').submit()"; echo "</script>"; }
Наверно это костыль, но я не знаю как ещё это сделать.
Мне надо получить данные в файл и уже на уровне сервера, в PHP коде выводить эти данные и т.д.
А то бывало в Console всё отправлялось, даже PHP мог в файл записать входные данные, т.е он их "видел".
Но вот выводить и работать с ними в коде - нет. Пустота была.
Может кто и подскажет как тут разрулить всё лучше. - EpIvIaK, так ты не отправляешь ничего, очевидно ты не совсем понимаешь как работает JS и PHP.
- EpIvIaK, я делал как то чат ..и по ходу дела несколько раз передавал из js в php. данные из js через jquery передавал, на php через post кажется принимал...как то так.
- rvitalia, рекомендую чат гпт попытать) Ты застрял на прописанных истинах, начини с основ, попроси у чат гпт примеры и пояснения.
- zkrvndm, вот как я показал выше код - отправляет. Протестировал. PHP уже по полной принимает всё, отображает, в переменные записывает.
Но и правда, в остальном тут и правда есть непонимание.
Всякие fetch, FormData, Аякс пробовал.
Данные так можно отослать серверу для файла или БД.Часто проблема новичков, что мы на локальной машине и как клиент и как сервер.
Это немного не даёт ощущение разницы. Когда мы как клиент, а где-то там сервер. Раздельно.
JS фурычит у Васи на его компьютере в браузере, а PHP там - на сервере. Но это в общем. А вот детали... Тут сложнее. Всё равно взаимодействие же идёт. Но не явно и просто.
Ну да, мы дилетанты видимо. Учимся. Оно и понятно. - zkrvndm, кстати спасибо за ИИ совет. Что-то я забыл про него. И правда так быстрее чем колупать форумы.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос

Для того чтобы правильно принять массив из FormData в PHP, необходимо выполнить несколько шагов.
Во-первых, в JavaScript нужно создать объект FormData и добавить в него необходимые данные, включая массив. Например:
```javascript
var formData = new FormData();
formData.append('name', 'John Doe');
formData.append('email', 'john.doe@example.com');
formData.append('hobbies[]', 'Reading');
formData.append('hobbies[]', 'Swimming');
```
Здесь мы добавляем в объект formData два хобби в виде массива.
Затем необходимо отправить этот объект на сервер, используя AJAX запрос. Например, с помощью jQuery:
```javascript
$.ajax({
url: 'process.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
console.log(response);
}
});
```
На стороне сервера, в файле process.php, мы можем получить данные из объекта FormData следующим образом:
```php
$name = $_POST['name'];
$email = $_POST['email'];
$hobbies = $_POST['hobbies'];
echo 'Name: ' . $name . '
';
echo 'Email: ' . $email . '
';
echo 'Hobbies: ' . implode(', ', $hobbies);
```
В данном примере мы получаем данные из объекта FormData и выводим их на экран. Обратите внимание, что данные из массива hobbies будут доступны в PHP как обычный массив.
Таким образом, правильно принять массив из FormData в PHP можно, используя объект FormData в JavaScript, AJAX запрос для отправки данных на сервер и обработку данных на стороне PHP.