Создание PHP класса для отправки 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;
(содержимое страницы)