Отправка POST данных в PHP: инструменты и практические примеры

Раздел: Веб-разработка на PHP -> POST запросы и методы

Отправка POST запроса в PHP: основные методы и их применение

Наиболее эффективным способом отправки POST запроса в PHP является использование библиотеки cURL. Этот инструмент предоставляет гибкие настройки, поддержку различных протоколов, таймауты и обработку ошибок.

Как отправить POST запрос с помощью cURL?

Базовая последовательность действий:

  1. Инициализировать сессию cURL с помощью curl_init().
  2. Установить URL через curl_setopt() с константой CURLOPT_URL.
  3. Указать метод POST: CURLOPT_POST = true.
  4. Передать данные: CURLOPT_POSTFIELDS.
  5. Выполнить запрос функцией curl_exec().
  6. Закрыть сессию curl_close().

<?php
$url = 'https://example.com/api';
$data = ['name' => 'John', 'email' => 'john@example.com'];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    // обработка ошибки
}
curl_close($ch);
?>

Этот код отправляет данные формы в кодировке application/x-www-form-urlencoded. Для JSON необходимо изменить заголовок Content-Type и формат данных.

Типичные ошибки при использовании cURL:

  • Ошибка SSL: отключение проверки сертификата с помощью CURLOPT_SSL_VERIFYPEER = false (не рекомендуется в production).
  • Неверный URL или отсутствие соединения.
  • Данные не переданы из-за неверного формата POSTFIELDS.
  • Забытый RETURNTRANSFER – ответ выводится напрямую.

Как отправить POST запрос без cURL, используя file_get_contents?

В PHP можно использовать потоковый контекст с функцией file_get_contents(). Этот метод подходит для простых запросов без сложной обработки ошибок.


<?php
$url = 'https://example.com/api';
$data = ['key' => 'value'];

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

$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === false) {
    // обработка ошибки
}
?>

Цель этого варианта – быстрая отправка без подключения дополнительных библиотек, но с ограниченными возможностями (нет поддержки таймаутов, куки, переадресаций).

Распространённые проблемы:

  • Отсутствие обработчика ошибок – функция возвращает false при любой нештатной ситуации.
  • Недоступность потоковых обёрток (allow_url_fopen = Off).
  • Проблемы с кодировкой данных.

Как отправить POST запрос с JSON данными?

Для отправки JSON необходимо установить заголовок Content-Type: application/json и передать сериализованную строку.


<?php
$url = 'https://example.com/api';
$data = ['user' => 'Alice', 'role' => 'admin'];
$jsonData = json_encode($data);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($jsonData)
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

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

Как отправить POST запрос с файлом?

Для загрузки файлов используется multipart/form-data. В cURL достаточно передать массив с файлом через CURLFile.


<?php
$url = 'https://example.com/upload';
$filePath = '/path/to/file.pdf';

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'file' => new CURLFile($filePath, 'application/pdf', 'document.pdf'),
    'description' => 'Uploaded file'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

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

Возможные сложности:

  • Необходимость указывать правильный MIME-тип.
  • Превышение лимита post_max_size или upload_max_filesize.
  • Ошибки при использовании устаревшего синтаксиса @filename (удалён в PHP 5.5).

Какие ещё библиотеки и классы позволяют отправлять POST запросы?

Можно использовать сторонние HTTP-клиенты, такие как Guzzle, Symfony HttpClient, или встроенные классы PHP (например, SoapClient для SOAP-сервисов). Однако для обычных REST запросов cURL остаётся стандартом де-факто.


// Пример с Guzzle (требуется composer)
use GuzzleHttp\Client;

$client = new Client();
$response = $client->post('https://example.com/api', [
    'form_params' => ['field' => 'value']
]);
$body = $response->getBody();

Общие рекомендации по безопасности:

  • Всегда проверять сертификаты SSL (не отключать verify peer в production).
  • Фильтровать и валидировать данные перед отправкой.
  • Устанавливать таймауты (CURLOPT_TIMEOUT) для предотвращения зависаний.

Расширенные примеры отправки POST запросов

1. cURL с обработкой ответа и ошибок

Пример

<?php
$url = 'https://httpbin.org/post';
$data = ['key1' => 'value1', 'key2' => 'value2'];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($data),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_VERBOSE => true
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);

if ($error) {
    echo "Ошибка: $error\n";
} else {
    echo "HTTP код: $httpCode\n";
    echo "Ответ: $response\n";
}
?>
HTTP код: 200
Ответ: {
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "key1": "value1",
    "key2": "value2"
  },
  ...
}

2. Отправка JSON и получение ответа в формате JSON

Пример

<?php
$url = 'https://jsonplaceholder.typicode.com/posts';
$postData = ['title' => 'foo', 'body' => 'bar', 'userId' => 1];
$json = json_encode($postData);

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

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

$decoded = json_decode($result, true);
print_r($decoded);
?>
Array
(
    [title] => foo
    [body] => bar
    [userId] => 1
    [id] => 101
)

3. Отправка multipart/form-data с несколькими файлами

Пример

<?php
$url = 'https://httpbin.org/post';
$fields = [
    'name' => 'Test',
    'file1' => new CURLFile('/tmp/photo.jpg', 'image/jpeg', 'photo.jpg'),
    'file2' => new CURLFile('/tmp/doc.pdf', 'application/pdf', 'doc.pdf')
];

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $fields,
    CURLOPT_RETURNTRANSFER => true
]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
{
  "files": {
    "file1": "data:image/jpeg;base64,...",
    "file2": "data:application/pdf;base64,..."
  },
  "form": {
    "name": "Test"
  }
}

4. Асинхронная отправка нескольких POST запросов с помощью curl_multi

Пример

<?php
$urls = [
    'https://httpbin.org/post',
    'https://httpbin.org/anything'
];
$data = ['msg' => 'Hello'];

$mh = curl_multi_init();
$handles = [];

foreach ($urls as $i => $url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($data),
        CURLOPT_RETURNTRANSFER => true
    ]);
    curl_multi_add_handle($mh, $ch);
    $handles[$i] = $ch;
}

$active = null;
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

foreach ($handles as $ch) {
    $response = curl_multi_getcontent($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    echo "Ответ [$httpCode]: " . substr($response, 0, 100) . "\n\n";
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);
?>
Ответ [200]: {
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "msg": "Hello"
  },
  ...
}

Ответ [200]: {
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "msg": "Hello"
  },
  ...
}

5. Использование stream_context_create с настройкой таймаута и игнорированием ошибок

Пример

<?php
$url = 'https://httpbin.org/post';
$data = ['x' => 1, 'y' => 2];
$options = [
    'http' => [
        'method' => 'POST',
        'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => http_build_query($data),
        'timeout' => 5,
        'ignore_errors' => true
    ],
    'ssl' => [
        'verify_peer' => true,
        'verify_peer_name' => true
    ]
];
$context = stream_context_create($options);
$result = @file_get_contents($url, false, $context);
if ($result === false) {
    $error = error_get_last();
    echo "Ошибка: " . $error['message'];
} else {
    echo $result;
}
?>
{
  "form": {
    "x": "1",
    "y": "2"
  }
}

6. Отправка POST запроса с базовой аутентификацией

Пример

<?php
$url = 'https://httpbin.org/basic-auth/user/pass';
$username = 'user';
$password = 'pass';

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => ['test' => 'value'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD => "$username:$password",
    CURLOPT_HTTPAUTH => CURLAUTH_BASIC
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "HTTP код: $httpCode\n";
echo $response;
?>
HTTP код: 200
{
  "authenticated": true,
  "user": "user"
}

Отправка POST запроса в PHP - comments

En
Posting php (php)