PHP POST JSON: способы и инструкции
Раздел: Веб-интеграция -> HTTP запросы
Основные подходы к отправке POST запроса с JSON телом
Для отправки POST запроса с телом в формате JSON на PHP существует несколько методов. Наиболее распространённым и гибким является использование cURL. Это решение рассматривается как базовое.
Решение с помощью cURL
cURL (Client URL Library) позволяет отправлять запросы с полным контролем заголовков, тела, таймаутов и сертификатов.
Как отправить JSON через POST с помощью cURL?
$data = ['name' => 'Иван', 'age' => 30];
$json = json_encode($data);
$ch = curl_init('https://example.com/api');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($json)
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (curl_error($ch)) {
$error = curl_error($ch);
} else {
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
}
curl_close($ch);
Возможные проблемы:
- Неверный Content-Type: сервер может не распознать JSON.
- Проблемы с SSL сертификатами: рекомендуется использовать CURLOPT_SSL_VERIFYPEER и CURLOPT_CAINFO.
- Кодировка: json_encode автоматически кодирует в UTF-8, следует убедиться, что данные в нужной кодировке.
- Если сервер ожидает application/json; charset=utf-8, это указывается в заголовке.
- Размер отправляемых данных: при больших объёмах требуется настройка memory_limit и времени выполнения.
Вариант с file_get_contents и stream context
Как отправить POST запрос без cURL, используя встроенные функции?
Если cURL недоступен, можно использовать file_get_contents с контекстом потока.
$data = ['key' => 'value'];
$json = json_encode($data);
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json' . chr(13).chr(10) .
'Content-Length: ' . strlen($json) . chr(13).chr(10),
'content' => $json
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://example.com/api', false, $context);
if ($response === false) {
$error = error_get_last();
}
Ограничения:
- file_get_contents блокирует выполнение скрипта до получения ответа.
- Сложнее обрабатывать ошибки HTTP (например, 404) - требуется парсить заголовки ответа через переменную $http_response_header.
- Не поддерживается настройка таймаутов напрямую; для этого используется параметр timeout в контексте.
Вариант с использованием библиотеки Guzzle
Как отправлять JSON POST запросы современным способом с помощью Composer пакета?
Guzzle - популярный HTTP клиент для PHP. Требует установки через Composer.
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
try {
$response = $client->post('https://example.com/api', [
'json' => ['name' => 'Анна', 'email' => 'anna@example.com'],
'headers' => ['X-Custom' => 'value']
]);
$body = $response->getBody()->getContents();
$status = $response->getStatusCode();
} catch (\Exception $e) {
$error = $e->getMessage();
}
Возможные сложности:
- Требуется установка (composer require guzzlehttp/guzzle).
- Версии PHP 7.2+ для Guzzle 7.
- Необходимо обрабатывать исключения (ConnectException, ClientException и др.).
- Автоматическое управление заголовками может не подходить для некоторых API.
Пример
// Пример 1: Отправка JSON с авторизацией Bearer token
$token = '...';
$data = ['action' => 'update', 'id' => 123];
$ch = curl_init('https://api.example.com/user');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $token
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo 'HTTP код: ' . $httpCode . '\n';
echo 'Ответ: ' . $response;
HTTP код: 200
Ответ: {"status":"ok"}
Пример
// Пример 2: Отправка JSON с проверкой SSL (для самоподписанных сертификатов)
$ch = curl_init('https://internal.api.local/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['test' => true]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false, // Только для разработки!
CURLOPT_SSL_VERIFYHOST => false,
]);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'cURL error: ' . curl_error($ch);
} else {
echo $response;
}
curl_close($ch);
{"message":"Test endpoint"}
Пример
// Пример 3: Асинхронная отправка нескольких POST запросов с curl_multi
$urls = ['https://api1.example.com', 'https://api2.example.com'];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['index' => $i]),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
]);
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh);
} while ($running > 0);
foreach ($handles as $ch) {
$response = curl_multi_getcontent($ch);
echo 'Ответ: ' . $response . '\n';
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
Ответ: {"id":1}
Ответ: {"id":2}
Пример
// Пример 4: Использование file_get_contents с настройкой таймаута
$data = ['operation' => 'get_status'];
$json = json_encode($data);
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json' . chr(13).chr(10) .
'Content-Length: ' . strlen($json) . chr(13).chr(10),
'content' => $json,
'timeout' => 10
]
];
$context = stream_context_create($options);
$response = @file_get_contents('https://example.com/status', false, $context);
if ($response === false) {
$error = error_get_last();
echo 'Ошибка: ' . $error['message'];
} else {
if (isset($http_response_header[0])) {
$statusLine = $http_response_header[0];
echo 'Статус: ' . $statusLine . '\n';
}
echo 'Ответ: ' . $response;
}
Статус: HTTP/1.1 200 OK
Ответ: {"status":"active"}
Пример
// Пример 5: Отправка JSON с Guzzle и обработкой исключений
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client(['base_uri' => 'https://api.example.com', 'timeout' => 5.0]);
try {
$response = $client->post('/v1/items', [
'json' => ['item' => ['name' => 'New Item', 'price' => 99.99]],
'headers' => ['Accept' => 'application/json']
]);
$body = $response->getBody();
$decoded = json_decode($body, true);
print_r($decoded);
} catch (RequestException $e) {
echo 'HTTP Error: ' . $e->getCode() . ' ' . $e->getMessage();
if ($e->hasResponse()) {
echo '\nResponse body: ' . $e->getResponse()->getBody();
}
} catch (\Exception $e) {
echo 'General error: ' . $e->getMessage();
}
Array
(
[id] => 42
[name] => New Item
[price] => 99.99
)
Обработка GET запросов в PHPHTTP клиент на PHPРабота с файлами по HTTP в PHPОтправка контента по HTTP в PHPОтправка HTTPS POST запросов в PHPPHP: отправка POST-запроса с JSONОбработка HTTP запросов в PHPPHP: установка Content-Type: application/jsonGET запрос в PHPPOST запрос в PHPОбработка запросов PHP сервераРедирект в PHPПередача параметра ID в PHPЗапрос страницы в PHPПолучение данных в PHPcURL в PHPFetch-запрос в PHP (cURL или file_get_contents)PHP работа с URL и HTTPPHP title (установка заголовка страницы)PHP запросы (SQL/HTTP)Обработка URL в PHPобработка форм в PHP
PHP: отправка POST-запроса с JSON - comments
En
Php post json (php)