Как отправить POST-запрос в PHP: от новичка до профи
Вы когда-нибудь сталкивались с ситуацией, когда вашему PHP-скрипту нужно «поговорить» с другим сервером? Отправить данные формы, вызвать внешний API или просто проверить, работает ли удаленный endpoint? Если да, то вы наверняка задавались вопросом: «How do I send a POST request with PHP?». Это один из самых популярных запросов на Stack Overflow, и неспроста — взаимодействие между серверами лежит в основе современного веба.
В этой статье мы разберем четыре проверенных способа отправки POST-запроса в PHP. Вы узнаете, как это сделать с помощью cURL, file_get_contents, stream_context_create и мощного HTTP-клиента Guzzle. Мы не просто покажем код — мы объясним, какой метод выбрать под вашу задачу и как избежать типичных ошибок.
Поехали! 🚀
Что такое POST-запрос и зачем он нужен в PHP?
POST — это один из методов HTTP-протокола, предназначенный для отправки данных на сервер. В отличие от GET, где параметры «светятся» в URL, POST передает данные в теле запроса. Это удобно, когда нужно:
- Отправить форму регистрации или заказа;
- Вызвать REST API (например, создать новую запись в CRM);
- Передать файл на удаленный сервер;
- Авторизоваться на стороннем сервисе.
В PHP нет встроенной функции «sendPostRequest()», но есть несколько гибких инструментов, которые позволяют это сделать. Давайте рассмотрим каждый из них.
Способ 1: cURL — универсальный солдат
cURL (Client URL Library) — это, пожалуй, самый популярный способ отправки HTTP-запросов в PHP. Он поддерживает кучу протоколов, умеет работать с SSL, куками, таймаутами и прокси. Если вы пишете что-то серьезнее учебного скрипта — присмотритесь к cURL.
Простой POST-запрос с cURL
Вот базовый пример, который отправляет POST-запрос на тестовый сервер JSONPlaceholder и выводит ответ:
// 1. Создаем новый ресурс cURL
$ch = curl_init();
// 2. Указываем URL endpoint
curl_setopt($ch, CURLOPT_URL, "https://jsonplaceholder.typicode.com/posts");
// 3. Говорим, что это POST-запрос
curl_setopt($ch, CURLOPT_POST, 1);
// 4. Передаем данные (массив PHP автоматически преобразуется в строку запроса)
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'title' => 'Мой первый пост',
'body' => 'Это тело поста',
'userId' => 1
]));
// 5. Возвращаем результат, а не выводим его напрямую
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 6. Выполняем запрос
$response = curl_exec($ch);
// 7. Проверяем на ошибки
if (curl_errno($ch)) {
echo 'Ошибка cURL: ' . curl_error($ch);
} else {
// 8. Закрываем соединение
curl_close($ch);
// 9. Выводим результат
echo $response;
}
POST с JSON и заголовками
Современные API чаще всего работают с JSON. Вот как отправить JSON-данные и установить правильный заголовок Content-Type:
$data = [
'email' => 'user@example.com',
'password' => 'secret123'
];
$ch = curl_init('https://api.example.com/login');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // Получаем HTTP-код ответа
curl_close($ch);
if ($httpCode === 200) {
$result = json_decode($response, true);
print_r($result);
} else {
echo "Ошибка: HTTP $httpCode";
}
Почему cURL? Он дает полный контроль: вы можете настроить таймаут (CURLOPT_TIMEOUT), следовать редиректам (CURLOPT_FOLLOWLOCATION), отправить файл (CURLFile) и даже работать с FTP. Единственный минус — код получается многословным.
Способ 2: file_get_contents + stream_context_create
Если вы не хотите подключать cURL (хотя он есть в 99% хостингов), можно использовать встроенные функции для работы с потоками. Этот метод короче, но менее гибкий.
Пример POST-запроса с file_get_contents
$postData = http_build_query([
'name' => 'Иван',
'message' => 'Привет, мир!'
]);
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
"Content-Length: " . strlen($postData) . "\r\n",
'content' => $postData
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://httpbin.org/post', false, $context);
if ($response === false) {
echo "Ошибка при отправке запроса";
} else {
echo $response;
}
Отправка JSON через stream_context
$jsonData = json_encode(['key1' => 'value1', 'key2' => 'value2']);
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n" .
"Content-Length: " . strlen($jsonData) . "\r\n",
'content' => $jsonData,
'ignore_errors' => true // Получать тело ответа даже при HTTP-ошибках
]
];
$context = stream_context_create($options);
$result = file_get_contents('https://api.example.com/data', false, $context);
echo $result;
Когда использовать? Для простых POST-запросов без сложных заголовков, таймаутов и SSL-сертификатов. Идеально подходит для быстрых прототипов и учебных задач. Но помните: этот метод не поддерживает асинхронные запросы и плохо работает с большими объемами данных.
Способ 3: Guzzle — современный HTTP-клиент
Guzzle — это PHP HTTP-клиент нового поколения. Он построен на PSR-7 (стандарт HTTP-сообщений) и умеет работать с промисами (асинхронность). Если вы используете фреймворк (Laravel, Symfony) или просто пишете современный код — Guzzle ваш выбор.
Сначала установите Guzzle через Composer:
composer require guzzlehttp/guzzle
Простой POST-запрос с Guzzle
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'base_uri' => 'https://jsonplaceholder.typicode.com',
'timeout' => 5.0,
]);
try {
$response = $client->post('/posts', [
'form_params' => [
'title' => 'Заголовок',
'body' => 'Текст поста',
'userId' => 1
]