Avatar ·

Как отправить POST-запрос на PHP: полное руководство с примерами

Всем привет! Я новичок в PHP и никак не могу разобраться с отправкой POST-запросов. Пишу небольшой парсер для своего проекта, и мне нужно отправлять данные на внешний API и получать ответ. Пробовал использовать file_get_contents с контекстом, но что-то пошло не так. Вот мой код: ```php $data = array('name' => 'Иван', 'email' => 'ivan@example.com'); $options = array( 'http' => array( 'method' => 'POST', 'content' => $data ) ); $context = stream_context_create($options); $result = file_get_contents('https://api.example.com/submit', false, $context); echo $result; ``` Но на выходе я получаю пустую строку или ошибку. Перерыл кучу форумов — одни советуют cURL, другие говорят, что нужно сериализовать данные. Я совсем запутался. Подскажите, как правильно отправить POST-запрос в PHP? Мне нужно передать массив данных (ассоциативный массив) и получить JSON-ответ от сервера. Буду благодарен за подробное объяснение с рабочими примерами. <<>>

Проблема в вашем коде

Ваш код не работает по двум причинам:

  • Вы передаёте массив $data как есть, а нужно преобразовать его в строку (например, в URL-кодированный запрос или JSON).
  • Не указан заголовок Content-Type, чтобы сервер понимал, в каком формате вы отправляете данные.

Решение 1: Использование cURL (рекомендуемый способ)

cURL — это мощная библиотека для работы с HTTP в PHP. Она поддерживает все методы, заголовки, таймауты и обработку ошибок. Вот рабочий пример:

<?php
// Данные для отправки
$data = array(
    'name' => 'Иван',
    'email' => 'ivan@example.com'
);

// Инициализируем cURL-сессию
$ch = curl_init('https://api.example.com/submit');

// Настройки запроса
curl_setopt_array($ch, [
    CURLOPT_POST => true,                          // Метод POST
    CURLOPT_POSTFIELDS => http_build_query($data), // Преобразуем массив в строку
    CURLOPT_RETURNTRANSFER => true,                // Возвращать результат в переменную
    CURLOPT_HTTPHEADER => [                        // Заголовки
        'Content-Type: application/x-www-form-urlencoded',
        'Accept: application/json'
    ],
    CURLOPT_TIMEOUT => 30,                         // Таймаут в секундах
    CURLOPT_SSL_VERIFYPEER => false                // Для тестов (в продакшне — true)
]);

// Выполняем запрос
$response = curl_exec($ch);

// Проверяем на ошибки
if (curl_errno($ch)) {
    echo 'Ошибка cURL: ' . curl_error($ch);
} else {
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo "HTTP-код: $httpCode\n";
    echo "Ответ: $response";
}

// Закрываем сессию
curl_close($ch);
?>

Решение 2: Отправка JSON (для REST API)

Если API принимает JSON, используйте этот вариант:

<?php
$data = ['name' => 'Иван', 'email' => 'ivan@example.com'];
$jsonData = json_encode($data);

$ch = curl_init('https://api.example.com/submit');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $jsonData,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($jsonData)
    ]
]);

$response = curl_exec($ch);
curl_close($ch);

// Декодируем JSON-ответ
$result = json_decode($response, true);
print_r($result);
?>

Решение 3: file_get_contents с контекстом (без cURL)

Если cURL недоступен, можно использовать file_get_contents, но нужно правильно настроить контекст:

<?php
$data = http_build_query(['name' => 'Иван', 'email' => 'ivan@example.com']);

$options = [
    'http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
                     "Content-Length: " . strlen($data) . "\r\n",
        'content' => $data
    ]
];

$context = stream_context_create($options);
$response = file_get_contents('https://api.example.com/submit', false, $context);

if ($response === false) {
    echo 'Ошибка при отправке запроса';
} else {
    echo $response;
}
?>

Что нужно запомнить

  • Всегда преобразуйте данные в строку (http_build_query или json_encode).
  • Указывайте правильный Content-Type.
  • Используйте cURL для сложных запросов — он гибче и надёжнее.
  • Всегда проверяйте HTTP-код ответа (200 — успех, 4xx/5xx — ошибки).
  • Для продакшена включайте проверку SSL-сертификата (CURLOPT_SSL_VERIFYPEER => true).

Теперь ваш парсер будет работать как часы!

<<>>

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

Для серьёзных проектов рекомендую перейти на Guzzle — это популярный HTTP-клиент для PHP с удобным интерфейсом. Он устанавливается через Composer:

composer require guzzlehttp/guzzle

Пример отправки POST-запроса с Guzzle:

<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;

$client = new Client(['base_uri' => 'https://api.example.com/']);

try {
    $response = $client->post('submit', [
        'form_params' => [
            'name' => 'Иван',
            'email' => 'ivan@example.com'
        ],
        'headers' => [
            'Accept' => 'application/json'
        ]
    ]);

    $body = $response->getBody()->getContents();
    $data = json_decode($body, true);
    print_r($data);
} catch (\GuzzleHttp\Exception\RequestException $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
?>

Почему Guzzle лучше?

  • Автоматически обрабатывает ошибки и статусы ответов.
  • Поддерживает асинхронные запросы.
  • Удобная работа с JSON, формами, файлами и куками.
  • Единый интерфейс для разных методов (GET, POST, PUT, DELETE).

Если ваш проект использует Composer — это лучший выбор для HTTP-запросов.