Введение: зачем PHP-разработчику уметь отправлять POST-запросы?
Представьте ситуацию: вы пишете сайт на PHP, и вам нужно отправить данные на другой сервер. Например, зарегистрировать пользователя через внешний API, отправить форму в CRM-систему или протестировать свой собственный обработчик POST-запросов. Это классическая задача, которую решает каждый веб-разработчик.
Вопрос "How do I send a POST request with PHP?" на Stack Overflow набрал сотни тысяч просмотров. И это не случайно: хотя PHP — мощный язык, у новичков часто возникает путаница: какой метод выбрать? Неужели нельзя просто взять и отправить данные?
Можно. И даже четырьмя разными способами. В этой статье мы разберем каждый из них, покажем реальные примеры кода на PHP, сравним производительность и подскажем, когда какой метод применять. К концу статьи вы будете чувствовать себя уверенно, отправляя POST-запросы в любом проекте.
Способ 1. Классика: cURL (самый гибкий и мощный)
cURL — это библиотека, которая есть практически на всех хостингах. Она поддерживает HTTPS, куки, заголовки, таймауты и многое другое. Если вам нужно отправить POST-запрос с максимальным контролем — выбирайте cURL.
Простой пример: отправка формы с полями name и email
<?php
$url = 'https://api.example.com/submit';
$data = [
'name' => 'Иван Петров',
'email' => 'ivan@example.com'
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
// Если нужно отправить JSON:
// curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
// curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
echo "Успешно! Ответ сервера: " . $response;
} else {
echo "Ошибка. HTTP код: " . $httpCode;
}
?>
Важные нюансы cURL:
- http_build_query() — превращает массив в строку вида
name=Иван&email=ivan@example.com. Это стандартный формат для форм. - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true) — чтобы результат запроса вернулся в переменную, а не выводился сразу.
- Всегда проверяйте HTTP-код ответа (200 — успех, 4xx/5xx — ошибка).
- Если сервер требует JSON: замените
http_build_queryнаjson_encodeи добавьте заголовокContent-Type: application/json.
Способ 2. Быстрый и простой: file_get_contents с контекстом
Многие знают file_get_contents() как функцию для чтения файлов. Но мало кто догадывается, что с помощью Stream Context она умеет отправлять POST-запросы. Это отличный вариант, если у вас простая задача и вы не хотите подключать сторонние библиотеки.
Пример отправки POST-запроса через file_get_contents
<?php
$url = 'https://api.example.com/submit';
$data = [
'name' => 'Иван Петров',
'email' => 'ivan@example.com'
];
$options = [
'http' => [
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === false) {
echo "Ошибка при отправке запроса";
} else {
echo "Ответ сервера: " . $result;
}
?>
Когда использовать этот метод?
- Когда нужно быстро протестировать отправку данных.
- Когда вы не хотите писать много кода с cURL.
- Минус: сложно обрабатывать ошибки (нет прямого доступа к HTTP-коду).
- Минус: не поддерживает куки и сложные сценарии.
Способ 3. Продвинутый: Stream Context с заголовками и таймаутом
Метод file_get_contents можно расширить, добавив больше опций в контекст. Например, установить таймаут, отправить JSON или добавить кастомные заголовки (авторизацию). Это уже почти полноценный HTTP-клиент.
Пример с JSON и Bearer-токеном
<?php
$url = 'https://api.example.com/user';
$data = [
'username' => 'john_doe',
'password' => 'secret123'
];
$jsonData = json_encode($data);
$options = [
'http' => [
'method' => 'POST',
'header' => [
"Content-Type: application/json",
"Authorization: Bearer YOUR_TOKEN_HERE",
"User-Agent: MyPHPApp/1.0"
],
'content' => $jsonData,
'timeout' => 10, // таймаут в секундах
'ignore_errors' => true // чтобы получить ответ даже при 4xx
]
];
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
// Получаем HTTP-код ответа
$http_response_header = $http_response_header ?? [];
$statusLine = $http_response_header[0] ?? '';
preg_match('/\d{3}/', $statusLine, $matches);
$httpCode = $matches[0] ?? 0;
echo "HTTP код: " . $httpCode . "\n";
echo "Ответ: " . $response;
?>
Совет: Если вы используете этот метод в продакшене, всегда устанавливайте timeout — иначе скрипт может зависнуть навсегда, если внешний сервер не отвечает.
Способ 4. Современный: Guzzle (для профессионалов)
Guzzle — это PHP-библиотека для работы с HTTP-запросами. Она устанавливается через Composer и используется в современных фреймворках (Laravel, Symfony). Если вы пишете что-то серьёзнее одного скрипта — используйте Guzzle.
Установка и пример
// Установка через Composer:
// composer require guzzlehttp/guzzle
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client([
'timeout' => 10.0,
'verify' => false // отключить проверку SSL (только для тестов!)
]);
try {
$response = $client->post('https://api.example.com/submit', [
'form_params' => [
'name' => 'Иван Петров',
'email' => 'ivan@example