Как построить HTTP-запрос к одному эндпоинту из PHP-скрипта

«Как построить HTTP-запрос к одному эндпоинту из PHP-скрипта» — вопрос из категории Сети, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для отправки HTTP-запросов из PHP я предпочитаю использовать библиотеку Guzzle за её удобный синтаксис и богатые возможности. Если же Guzzle недоступен, использую расширение cURL.

Пример с Guzzle (рекомендованный способ):

use GuzzleHttpClient;
use GuzzleHttpExceptionRequestException;

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

try {
    $response = $client->request('GET', '/users/1', [
        'headers' => [
            'Authorization' => 'Bearer ' . $apiToken,
            'Accept'        => 'application/json',
        ],
        'timeout' => 10, // Таймаут в секундах
    ]);

    $statusCode = $response->getStatusCode(); // e.g., 200
    $body = $response->getBody()->getContents();
    $userData = json_decode($body, true);

} catch (RequestException $e) {
    // Логируем ошибку
    error_log('API Request failed: ' . $e->getMessage());
    // Обрабатываем в зависимости от статуса
    if ($e->hasResponse()) {
        $statusCode = $e->getResponse()->getStatusCode();
    }
}

Пример с нативным cURL (если Guzzle не установлен):

$ch = curl_init('https://api.example.com/users/1');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiToken,
        'Accept: application/json',
    ],
    CURLOPT_TIMEOUT => 10,
    CURLOPT_SSL_VERIFYPEER => true, // Всегда проверять SSL!
]);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    throw new RuntimeException('cURL error: ' . curl_error($ch));
}

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

if ($httpCode >= 200 && $httpCode < 300) {
    $userData = json_decode($response, true);
} else {
    // Обработка HTTP-ошибок (4xx, 5xx)
    throw new RuntimeException("API returned status: {$httpCode}");
}

Ключевые моменты: Всегда обрабатываю ошибки сети и HTTP-статусы, устанавливаю разумные таймауты и обязательно проверяю SSL-сертификаты в продакшене.