Создание PHP класса для отправки HTTP запросов

Раздел: Сетевые запросы -> HTTP классы

Создание класса HTTP запросов на PHP

Наиболее эффективное решение для работы с HTTP в PHP – использование расширения cURL. Класс Request, реализованный на cURL, позволяет гибко управлять заголовками, телом запроса, таймаутами и обрабатывать ошибки.


class Request {
    private $ch;
    private $url;
    private $method = 'GET';
    private $headers = [];
    private $body = null;
    private $options = [];

    public function __construct($url) {
        $this->url = $url;
        $this->ch = curl_init();
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($this->ch, CURLOPT_HEADER, false);
        curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($this->ch, CURLOPT_TIMEOUT, 30);
    }

    public function setMethod($method) {
        $this->method = strtoupper($method);
        return $this;
    }

    public function setHeaders(array $headers) {
        $this->headers = $headers;
        return $this;
    }

    public function setBody($body) {
        $this->body = $body;
        return $this;
    }

    public function setOption($key, $value) {
        $this->options[$key] = $value;
        return $this;
    }

    public function send() {
        curl_setopt($this->ch, CURLOPT_URL, $this->url);
        curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->method);
        if (!empty($this->headers)) {
            curl_setopt($this->ch, CURLOPT_HTTPHEADER, $this->headers);
        }
        if ($this->body !== null) {
            curl_setopt($this->ch, CURLOPT_POSTFIELDS, $this->body);
        }
        foreach ($this->options as $key => $value) {
            curl_setopt($this->ch, $key, $value);
        }
        $response = curl_exec($this->ch);
        $info = curl_getinfo($this->ch);
        $error = curl_error($this->ch);
        curl_close($this->ch);
        if ($error) {
            throw new \RuntimeException("cURL error: $error");
        }
        return ['body' => $response, 'info' => $info];
    }
}
    

Php class request (класс для работы с http запросами в php)

Класс инкапсулирует инициализацию сеанса cURL, установку общих параметров и предоставляет интерфейс для настройки запроса. Метод send() выполняет запрос и возвращает массив с содержимым ответа и информацией о нём.

Пример использования:


$req = new Request('https://api.example.com/data');
$req->setMethod('POST');
$req->setHeaders(['Content-Type: application/json', 'Authorization: Bearer token']);
$req->setBody(json_encode(['key' => 'value']));
$result = $req->send();
echo $result['body'];
    

Типичная ошибка: если сервер использует самоподписанный SSL сертификат, cURL может выдать ошибку. Решение: установить опцию CURLOPT_SSL_VERIFYPEER в false, но это снижает безопасность. Лучше добавить сертификат в доверенные.


$req->setOption(CURLOPT_SSL_VERIFYPEER, false);
$req->setOption(CURLOPT_SSL_VERIFYHOST, false);
        

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

Если расширение cURL не установлено, можно воспользоваться функцией file_get_contents с потоковым контекстом. Такой подход проще, но менее гибок.


function sendHttpRequest($url, $method = 'GET', $headers = [], $body = null) {
    $opts = [
        'http' => [
            'method' => $method,
            'header' => implode("\r\n", $headers),
            'content' => $body,
            'ignore_errors' => true,
            'timeout' => 30
        ]
    ];
    if ($method === 'GET') {
        unset($opts['http']['content']);
    }
    $context = stream_context_create($opts);
    $result = file_get_contents($url, false, $context);
    if ($result === false) {
        throw new \RuntimeException('Ошибка при выполнении запроса');
    }
    return $result;
}
    

Ограничения: нельзя управлять редиректами, сложно получить заголовки ответа. Для работы с HTTPS нужны настройки SSL в контексте.

Проблема: file_get_contents может не выполнять запросы к HTTPS, если в php.ini отключён allow_url_fopen. Решение: включить директиву или использовать cURL.

Как использовать библиотеку Guzzle для HTTP запросов?

Guzzle – популярная PHP библиотека для HTTP, основанная на PSR-7 и PSR-18. Она предоставляет мощный и удобный интерфейс, поддерживает асинхронные запросы.


require 'vendor/autoload.php';
use GuzzleHttp\Client;
$client = new Client();
$response = $client->request('POST', 'https://api.example.com/data', [
    'headers' => ['Authorization' => 'Bearer token'],
    'json' => ['key' => 'value']
]);
echo $response->getBody();
    

Guzzle требует установки через Composer, но предлагает богатые возможности: пулы соединений, middleware, обработку ошибок.

Ошибка: если не установлен пакет, вызов метода приведёт к фатальной ошибке. Решение: выполнить composer require guzzlehttp/guzzle.

Расширенные примеры работы с HTTP классом

Пример 1: отправка GET запроса с параметрами и обработка ответа в JSON

Пример

$req = new Request('https://jsonplaceholder.typicode.com/posts');
$req->setMethod('GET');
$req->setOption(CURLOPT_TIMEOUT, 5);
$result = $req->send();
$data = json_decode($result['body'], true);
print_r($data[0]);
Array
(
    [userId] => 1
    [id] => 1
    [title] => sunt aut facere repellat provident occaecati excepturi optio reprehenderit
    [body] => quia et suscipit...
)

Пример 2: отправка POST запроса с JSON телом и получение кода ответа

Пример

$req = new Request('https://jsonplaceholder.typicode.com/posts');
$req->setMethod('POST');
$req->setHeaders(['Content-Type: application/json']);
$req->setBody(json_encode(['title' => 'foo', 'body' => 'bar', 'userId' => 1]));
$result = $req->send();
echo 'HTTP code: ' . $result['info']['http_code'];
echo 'Response: ' . $result['body'];
HTTP code: 201
Response: {
  "title": "foo",
  "body": "bar",
  "userId": 1,
  "id": 101
}

Пример 3: загрузка файла (multipart/form-data) с помощью cURL

Пример

$req = new Request('https://httpbin.org/post');
$req->setMethod('POST');
$req->setOption(CURLOPT_POSTFIELDS, [
    'file' => new CURLFile('/path/to/file.txt', 'text/plain', 'file.txt')
]);
$result = $req->send();
echo $result['body'];
{
  "files": {},
  "form": {},
  "data": "",
  "headers": {
    "Content-Type": "multipart/form-data; boundary=------------------------...",
    ...
  }
}

Пример 4: асинхронные запросы с Guzzle

Пример

require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client(['base_uri' => 'https://httpbin.org']);
$promises = [
    'one'   => $client->getAsync('/delay/1'),
    'two'   => $client->getAsync('/delay/2'),
    'three' => $client->getAsync('/delay/3'),
];
$results = Promise\settle($promises)->wait();
foreach ($results as $key => $result) {
    if ($result['state'] === 'fulfilled') {
        echo "$key: " . $result['value']->getStatusCode() . "\n";
    }
}
one: 200
two: 200
three: 200

Пример 5: прокси через file_get_contents

Пример

$url = 'http://example.com';
$proxy = 'tcp://proxy.example.com:8080';
$opts = [
    'http' => [
        'method' => 'GET',
        'proxy' => $proxy,
        'request_fulluri' => true
    ]
];
$context = stream_context_create($opts);
$result = file_get_contents($url, false, $context);
echo $result;
(содержимое страницы)

Класс для работы с HTTP запросами в PHP - comments

En
Php class request (php)