Ответ
В PHP для чтения "сырых" данных тела HTTP-запроса (для методов POST, PUT, PATCH, DELETE) используется поток php://input. Это предпочтительный способ, так как $_POST работает только для данных с content-type application/x-www-form-urlencoded или multipart/form-data.
Базовый пример чтения тела PUT-запроса:
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
// Получаем необработанное тело запроса как строку
$rawInput = file_get_contents('php://input');
// Далее парсим в зависимости от формата
// 1. Если ожидается JSON:
$data = json_decode($rawInput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400); // Bad Request
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
// Теперь $data — ассоциативный массив с данными
// echo $data['name'];
}
Важные нюансы работы с php://input:
- Доступен только один раз: Поток
php://inputне буферизуется. После чтенияfile_get_contents('php://input')он становится пустым. Если нужно использовать данные несколько раз, сохраните их в переменную. - Не работает с
multipart/form-data: Для загрузки файлов через PUT (что редкость) стандартно используется POST.php://inputне будет содержать загруженные файлы в таком случае. - Для больших данных: Используйте чтение чанками, чтобы не загружать всё в память.
$putData = ''; $handle = fopen('php://input', 'r'); while (!feof($handle)) { $putData .= fread($handle, 8192); } fclose($handle); - Определение типа контента: Всегда проверяйте заголовок
Content-Type($_SERVER['CONTENT_TYPE']), чтобы понять, как парсить данные (JSON, XML, plain text).
Альтернативный подход с parse_str (для form-encoded данных):
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
$input = file_get_contents('php://input');
parse_str($input, $parsedData); // Преобразует строку 'name=John&age=30' в массив
// $parsedData['name'] будет 'John'
} Ответ 18+ 🔞
А, ну это же классика, ёпта! Сидишь такой, пишешь свой API, и тут бац — нужно данные из PUT-запроса вытащить. А $_POST нихуя не работает, пустой как твои карманы после зарплаты. Вот тут-то и вспоминаешь про php://input, старину проверенного.
Смотри, в чём прикол. Этот php://input — это как читать мысли запроса напрямую, в обход всех этих дурацких формальностей. $_POST — он только для двух конкретных типов контента работает: application/x-www-form-urlencoded (обычная форма) и multipart/form-data (когда файлы шлёшь). А если тебе JSON прилетел, или XML, или просто текст — то $_POST будет пустым, и ты охуеешь, думая, что данные не дошли.
Вот самый простой способ, как с этим потоком работать. Допустим, ловишь PUT-запрос:
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
// Берёшь и просто выгребаешь всё, что в теле запроса лежит
$rawInput = file_get_contents('php://input');
// А дальше уже думаешь, что с этим делать. Если JSON пришёл:
$data = json_decode($rawInput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400); // Клиент — пидарас шерстяной, прислал херню
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
// Всё, $data теперь твой массив, работай с ним.
// echo $data['name'];
}
Но, чувак, есть важные нюансы, про которые забывать нельзя, а то будет тебе хиросима и нигерсраки.
- Прочитал один раз — и всё. Этот поток
php://input— не буферизованный. Прочитал его черезfile_get_contents()— и он опустел, как бутылка после хорошей пятницы. Хочешь использовать данные в нескольких местах? Сохраняй в переменную, не будь распиздяем. - С файлами через PUT — нихуя не выйдет. Если кто-то взбредёт в голову слать файлы через PUT с
multipart/form-data(что само по себе — мудя редкостная), тоphp://inputтебе нихуя не покажет. Для файлов — это POST-метод царь и бог. - Если данных овердохуища. Читай чанками, а то оперативку всю сожрёшь.
$putData = ''; $handle = fopen('php://input', 'r'); while (!feof($handle)) { $putData .= fread($handle, 8192); } fclose($handle); - Всегда смотри, что тебе шлют. Проверяй заголовок
Content-Type($_SERVER['CONTENT_TYPE']), чтобы понять, JSON это, XML или ещё какая-нибудь пиздопроебибна. Парси соответственно.
Ну и есть ещё один способ, если тебе старый-добрый URL-encoded формат прилетел (типа name=John&age=30). Можно parse_str использовать:
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
$input = file_get_contents('php://input');
parse_str($input, $parsedData); // Магия! Строка превращается в массив.
// $parsedData['name'] будет 'John'
}
Вот и вся наука. Главное — помни про поток, и доверия к $_POST в таких случаях — ебать ноль.