Практическое применение HTTP в PHP с примерами кода
HTTP соединения в PHP: обзор методов
Как выполнить HTTP запрос с полным контролем всех параметров?
Наиболее эффективным и гибким решением для работы с HTTP в PHP является расширение cURL. Оно поддерживает множество протоколов, позволяет настраивать заголовки, cookie, таймауты, работу с SSL сертификатами, а также выполнять POST, PUT и другие методы. cURL работает как с синхронными, так и с асинхронными запросами (через curl_multi).
<?php
$ch = curl_init('https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer token123']);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
// обработка ошибки
}
curl_close($ch);
?>
Php socket connection (сокетное соединение в php)
Типичные проблемы: неверный SSL сертификат (CURLOPT_SSL_VERIFYPEER), превышение времени ожидания (CURLOPT_TIMEOUT), ошибки DNS. Решение: установить CURLOPT_SSL_VERIFYPEER = false для тестовой среды, увеличить таймаут, проверить имя хоста.
Цель использования: когда требуется тонкая настройка запросов, поддержка различных протоколов, работа с большими объёмами данных или параллельные запросы.
Как сделать простой GET запрос без дополнительных библиотек?
Для простых GET запросов подходит встроенная функция file_get_contents. Она читает удалённый файл по URL, возвращает содержимое. Для настройки заголовков и других параметров требуется дополнительно создать потоковый контекст.
<?php
$url = 'https://api.example.com/data';
$response = file_get_contents($url);
if ($response === false) {
// ошибка
}
?>
Php connect to server (подключение к php серверу)
Проблема: отсутствие контроля над запросом, невозможность отправки POST или настройки таймаута без stream_context. Для POST нужно использовать контекст.
Случаи использования: быстрые прототипы, чтение публичных данных, когда не нужны заголовки авторизации.
Как отправить POST запрос с заголовками используя только стандартные средства?
Функция stream_context_create позволяет задать контекст потока, включая HTTP метод, заголовки и тело запроса. Затем file_get_contents использует этот контекст.
<?php
$data = http_build_query(['key' => 'value']);
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" .
"Authorization: Bearer token",
'content' => $data,
'timeout' => 10
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://api.example.com/submit', false, $context);
?>
Http connection php (http-соединение в php)
Ошибки: неправильный синтаксис заголовков (требуется \r\n, не \n), некорректный content при JSON. Решение: использовать json_encode для JSON и устанавливать Content-Type: application/json.
Подходит для простых POST запросов без сложной обработки ответа.
Как установить соединение на низком уровне через сокеты?
Функция fsockopen открывает TCP сокет к хосту. Затем вручную формируется HTTP запрос и читается ответ. Полный контроль, но много ручной работы.
<?php
$fp = fsockopen('ssl://api.example.com', 443, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)\n";
} else {
$out = "GET /data HTTP/1.1\r\n";
$out .= "Host: api.example.com\r\n";
$out .= "Connection: Close\r\n\r\n";
fwrite($fp, $out);
while (!feof($fp)) {
echo fgets($fp, 128);
}
fclose($fp);
}
?>
Проблемы: необходимо разбирать HTTP ответ (отделять заголовки от тела), обрабатывать chunked encoding, управлять buffering. Очень легко ошибиться.
Используется только для обучения или в крайних случаях, когда нужна максимальная производительность на уровне сокетов.
Расширенные примеры HTTP соединений в PHP
Пример 1: cURL с обработкой ошибок и SSL
Полный GET запрос с проверкой сертификата и обработкой таймаута.
<?php
$ch = curl_init('https://jsonplaceholder.typicode.com/posts/1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_CAINFO => '/path/to/cacert.pem',
CURLOPT_TIMEOUT => 5,
CURLOPT_USERAGENT => 'PHP cURL'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
echo 'Ошибка cURL: ' . curl_error($ch);
} elseif ($httpCode !== 200) {
echo "HTTP код: $httpCode";
} else {
echo $response;
}
curl_close($ch);
?>
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit..."
}
Пример 2: POST запрос с JSON через cURL
<?php
$data = json_encode(['title' => 'foo', 'body' => 'bar', 'userId' => 1]);
$ch = curl_init('https://jsonplaceholder.typicode.com/posts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
],
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
echo "HTTP статус: " . $info['http_code'] . "\n";
echo $response;
?>
HTTP статус: 201
{
"title": "foo",
"body": "bar",
"userId": 1,
"id": 101
}
Пример 3: file_get_contents с контекстом для POST с JSON
<?php
$data = json_encode(['name' => 'John']);
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n" .
"Accept: application/json\r\n",
'content' => $data,
'ignore_errors' => true
]
];
$context = stream_context_create($options);
$result = file_get_contents('https://httpbin.org/post', false, $context);
if ($result === false) {
echo 'Ошибка запроса';
} else {
echo $result;
}
?>
{
"args": {},
"data": "{\"name\":\"John\"}",
"files": {},
"form": {},
...
}
Пример 4: параллельные запросы через curl_multi
<?php
$urls = [
'https://api.github.com/users/octocat',
'https://api.github.com/users/defunkt',
'https://api.github.com/users/mojombo'
];
$multiHandle = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERAGENT => 'PHP'
]);
curl_multi_add_handle($multiHandle, $ch);
$handles[$i] = $ch;
}
$running = null;
do {
curl_multi_exec($multiHandle, $running);
} while ($running > 0);
foreach ($handles as $i => $ch) {
$response = curl_multi_getcontent($ch);
$info = curl_getinfo($ch);
echo "URL $i: HTTP " . $info['http_code'] . "\n";
// парсим ответ...
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
curl_multi_close($multiHandle);
?>
URL 0: HTTP 200 URL 1: HTTP 200 URL 2: HTTP 200
Пример 5: fsockopen с полным разбором ответа
<?php
$host = 'example.com';
$port = 80;
$fp = fsockopen($host, $port, $errno, $errstr, 10);
if (!$fp) {
die("$errstr ($errno)");
}
$request = "GET / HTTP/1.1\r\n" .
"Host: $host\r\n" .
"Connection: close\r\n\r\n";
fwrite($fp, $request);
$response = '';
while (!feof($fp)) {
$response .= fgets($fp, 4096);
}
fclose($fp);
// Разделяем заголовки и тело
list($headers, $body) = explode("\r\n\r\n", $response, 2);
echo "Заголовки:\n$headers\n\n";
echo "Тело (первые 200 символов):\n" . substr($body, 0, 200);
?>
Заголовки: HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 ... Тело (первые 200 символов): <!doctype html> <html> <head> ...