Как правильно отправить POST-запрос через cURL в PHP? Полный пример с обработкой ошибок
Полный рабочий пример POST-запроса через cURL с обработкой ошибок
Вот правильный и надёжный способ отправки POST-запроса через cURL в PHP. Я разберу каждую часть кода.
<?php
function sendPostRequest($url, $data, $useJson = false) {
// Инициализируем сессию cURL
$ch = curl_init();
// Базовые настройки
curl_setopt_array($ch, [
CURLOPT_URL => $url, // URL назначения
CURLOPT_POST => true, // Метод POST
CURLOPT_RETURNTRANSFER => true, // Возвращать ответ как строку
CURLOPT_TIMEOUT => 30, // Таймаут выполнения (сек)
CURLOPT_CONNECTTIMEOUT => 10, // Таймаут соединения (сек)
CURLOPT_FOLLOWLOCATION => true, // Следовать редиректам
CURLOPT_MAXREDIRS => 5, // Максимум редиректов
CURLOPT_SSL_VERIFYPEER => true, // Проверять SSL сертификат
CURLOPT_SSL_VERIFYHOST => 2, // Проверять имя хоста
]);
// Подготовка данных
if ($useJson) {
// Если нужно отправить JSON
$jsonData = json_encode($data, JSON_UNESCAPED_UNICODE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData)
]);
} else {
// Обычная POST-форма (application/x-www-form-urlencoded)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
}
// Выполняем запрос
$response = curl_exec($ch);
// Проверяем на ошибки
$error = '';
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
$error = 'cURL Error: ' . curl_error($ch);
} elseif ($httpCode >= 400) {
$error = "HTTP Error: {$httpCode}. Response: " . substr($response, 0, 200);
}
// Закрываем сессию
curl_close($ch);
// Возвращаем результат
return [
'success' => empty($error),
'http_code' => $httpCode,
'data' => $response,
'error' => $error
];
}
// Пример использования для обычных POST-данных
$result = sendPostRequest('https://api.example.com/submit', [
'name' => 'Иван',
'email' => 'ivan@example.com'
]);
// Пример для JSON
$resultJson = sendPostRequest('https://api.example.com/json-endpoint', [
'user' => ['name' => 'Иван', 'role' => 'admin']
], true);
// Обработка результата
if ($result['success']) {
echo "Успешно! Код: {$result['http_code']}<br>";
echo "Ответ: " . htmlspecialchars($result['data']);
} else {
echo "Ошибка: {$result['error']}";
}
?>
Объяснение ключевых моментов:
- CURLOPT_RETURNTRANSFER = true — обязательно! Без этого curl_exec() выводит ответ сразу в браузер, а не возвращает его в переменную.
- http_build_query() — правильно кодирует массив для передачи как form-data. Без этого могут быть проблемы с кириллицей и спецсимволами.
- Таймауты — CURLOPT_TIMEOUT и CURLOPT_CONNECTTIMEOUT спасут от зависания скрипта, если сервер не отвечает.
- Проверка ошибок — curl_errno() ловит технические ошибки (нет соединения, таймаут), а HTTP-код >= 400 — ошибки сервера.
- SSL проверка — отключать CURLOPT_SSL_VERIFYPEER крайне не рекомендуется в production, это уязвимость.
Дополнительные полезные настройки:
// Если нужно отправить файл
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'file' => new CURLFile('/path/to/file.pdf', 'application/pdf', 'document.pdf')
]);
// Если нужно отправить сырые данные
curl_setopt($ch, CURLOPT_POSTFIELDS, 'raw_data_here');
// Если нужно добавить кастомные заголовки
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer token123',
'X-Custom-Header: value'
]);
Этот код надёжно работает с любыми API и обрабатывает все типичные ошибки. Сохраните его как вспомогательную функцию в вашем проекте.
<<Альтернативный подход: использование библиотеки Guzzle
Если вы часто работаете с HTTP-запросами, рекомендую перейти на Guzzle — это современная PHP-библиотека, которая делает код чище и безопаснее.
// Установка: composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client([
'timeout' => 30,
'verify' => true // SSL проверка
]);
try {
// Обычный POST
$response = $client->post('https://api.example.com/submit', [
'form_params' => [
'name' => 'Иван',
'email' => 'ivan@example.com'
]
]);
// Или JSON
$response = $client->post('https://api.example.com/json', [
'json' => [
'user' => ['name' => 'Иван']
],
'headers' => [
'Authorization' => 'Bearer token123'
]
]);
echo $response->getBody();
echo "HTTP код: " . $response->getStatusCode();
} catch (RequestException $e) {
echo "Ошибка: " . $e->getMessage();
if ($e->hasResponse()) {
echo "Ответ сервера: " . $e->getResponse()->getBody();
}
}
Преимущества Guzzle:
- Автоматическая обработка JSON (сериализация/десериализация)
- Понятные исключения вместо ручной проверки ошибок
- Поддержка асинхронных запросов
- Автоматическое управление соединениями (keep-alive)
- Лучшая безопасность (защита от SSRF, правильная валидация URL)
Guzzle — это стандарт де-факто для HTTP-запросов в современном PHP. Он используется в Laravel, Symfony и большинстве фреймворков.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги