Avatar ·

Как получить и обработать JSON данные из POST запроса в PHP?

Всем привет! Я новичок в PHP и пытаюсь разобраться с REST API. Мне нужно написать скрипт, который принимает JSON данные через POST запрос и сохраняет их в базу данных. Проблема в том, что я не могу получить эти данные стандартным способом. Когда я отправляю обычную форму с Content-Type: application/x-www-form-urlencoded, то всё работает через $_POST. Но как только я переключаюсь на JSON (Content-Type: application/json), массив $_POST оказывается пустым. Вот мой текущий код: ```php ``` Я отправляю запрос через Postman с таким телом: ```json { "name": "Иван", "email": "ivan@example.com", "age": 28 } ``` Но в файл log.txt записывается пустой массив. Я читал, что для JSON нужно использовать php://input, но не совсем понимаю, как это работает и как правильно обработать полученные данные. Подскажите, пожалуйста, как правильно получить JSON из POST запроса в PHP? Нужно ли как-то специально настраивать сервер или это делается на уровне кода? И как потом работать с этими данными, например, извлечь отдельные поля? Заранее спасибо за помощь! <<>>

Правильный способ получения JSON из POST запроса

Вы абсолютно правы — для получения JSON данных через POST запрос в PHP нельзя использовать суперглобальный массив $_POST. Он заполняется только при отправке данных в формате application/x-www-form-urlencoded или multipart/form-data. Когда клиент отправляет JSON с заголовком Content-Type: application/json, PHP не парсит его автоматически.

Для получения "сырого" тела запроса используется поток php://input. Вот правильная реализация:

<?php
// receive.php

// Получаем сырые данные из тела запроса
$json = file_get_contents('php://input');

// Проверяем, что данные получены
if ($json === false) {
    http_response_code(400);
    echo json_encode(['error' => 'Не удалось прочитать тело запроса']);
    exit;
}

// Декодируем JSON в массив (второй параметр true)
$data = json_decode($json, true);

// Проверяем ошибки декодирования
if (json_last_error() !== JSON_ERROR_NONE) {
    http_response_code(400);
    echo json_encode([
        'error' => 'Некорректный JSON',
        'details' => json_last_error_msg()
    ]);
    exit;
}

// Теперь можно работать с данными
$name = $data['name'] ?? null;
$email = $data['email'] ?? null;
$age = $data['age'] ?? null;

// Пример сохранения в файл
file_put_contents('log.txt', print_r($data, true));

// Отправляем ответ клиенту
http_response_code(200);
echo json_encode([
    'status' => 'success',
    'message' => 'Данные получены',
    'received' => $data
]);
?>

Ключевые моменты

  • file_get_contents('php://input') — читает всё тело запроса как строку
  • json_decode($json, true) — преобразует JSON строку в ассоциативный массив PHP
  • Всегда проверяйте ошибки с помощью json_last_error()
  • Используйте http_response_code() для корректной обработки ошибок

Дополнительные рекомендации

Если вы используете современные фреймворки (Laravel, Symfony), они уже имеют встроенные методы для работы с JSON. Но чистый PHP требует ручного парсинга. Вот ещё один пример с обработкой разных Content-Type:

<?php
// Универсальный обработчик
function getRequestData() {
    $contentType = $_SERVER['CONTENT_TYPE'] ?? '';
    
    if (stripos($contentType, 'application/json') !== false) {
        // JSON запрос
        $json = file_get_contents('php://input');
        return json_decode($json, true) ?? [];
    }
    
    // Обычная форма
    return $_POST;
}

$data = getRequestData();
// Дальше работаем с $data как с обычным массивом
?>

Тестирование через Postman

Убедитесь, что в Postman вы:

  • Выбрали метод POST
  • В Body выбрали "raw" и формат JSON
  • Добавили заголовок Content-Type: application/json (Postman добавляет его автоматически при выборе JSON)

После этого ваш скрипт будет корректно принимать и обрабатывать JSON данные.

<<>>

Альтернативный подход с использованием потоков

Можно также использовать более гибкий способ чтения данных через потоковый интерфейс, особенно если вы ожидаете большие объёмы JSON данных:

<?php
// Чтение через поток
$stream = fopen('php://input', 'r');
$json = stream_get_contents($stream);
fclose($stream);

$data = json_decode($json, true);

// Проверка
if (is_array($data) && !empty($data)) {
    // Обработка данных
    $response = [
        'name' => htmlspecialchars($data['name'] ?? ''),
        'email' => filter_var($data['email'] ?? '', FILTER_VALIDATE_EMAIL)
    ];
    
    echo json_encode(['success' => true, 'data' => $response]);
} else {
    http_response_code(400);
    echo json_encode(['success' => false, 'error' => 'Некорректные данные']);
}
?>

Этот метод особенно полезен, если вы работаете с большими полезными нагрузками, так как позволяет читать данные частями. Однако для большинства случаев file_get_contents() более чем достаточно.

Важно помнить: php://input доступен только для чтения один раз за запрос. Если вы прочитали его в одном месте скрипта, повторное чтение вернёт пустую строку. Поэтому всегда сохраняйте результат в переменную.