GET запросы: от простых функций до cURL
Основные способы отправки GET запросов в PHP
Наиболее эффективное и гибкое решение - использование расширения cURL. Оно позволяет управлять заголовками, таймаутами, обрабатывать перенаправления и проверять ошибки. cURL доступен в большинстве установок PHP, но его присутствие необходимо явно проверить.
// Пример отправки GET запроса через cURL
$url = 'https://api.example.com/data';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
if (curl_error($ch)) {
// обработка ошибки
$error = curl_error($ch);
}
curl_close($ch);
Php отправить get (отправка get запроса в php)
Возвращаемые данные могут быть пустыми, если сервер не ответил. Проблема: если расширение curl не установлено, вызов curl_init вернёт false.
Ошибка: Call to undefined function curl_init. Решение: установить модуль php-curl, например, в Ubuntu: sudo apt install php-curl, или раскомментировать строку extension=curl в php.ini.
Как отправить GET запрос без внешних библиотек?
Встроенная функция file_get_contents с созданием контекста потока (stream context) позволяет получать содержимое URL. Этот способ подходит для простых запросов, когда не требуется детального управления сессией.
$url = 'https://api.example.com/data';
$options = [
'http' => [
'method' => 'GET',
'header' => "User-Agent: Mozilla/5.0\r\n"
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
if ($result === false) {
// Обработка ошибки
}
Проблема: file_get_contents не генерирует исключение, а возвращает false при ошибке (недоступный сервер, тайм-аут). Решение: явная проверка на false и использование подавления ошибок с пользовательской обработкой через set_error_handler.
Как прочитать содержимое страницы через поток?
Функция fopen с обёрткой HTTP позволяет открыть удалённый файл и читать его построчно или полностью. Это даёт больший контроль над процессом чтения, особенно для больших объёмов данных.
$url = 'https://example.com/data.txt';
$handle = fopen($url, 'r');
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
echo $buffer;
}
fclose($handle);
}
Проблема: директива allow_url_fopen должна быть включена в php.ini, иначе fopen для URL вернёт false. Решение: изменить настройку сервера или использовать cURL.
Как вручную сформировать HTTP GET запрос через сокеты?
Для низкоуровневого доступа можно использовать функции работы с сокетами. Этот метод редко применяется в реальных проектах из-за сложности, но полезен для понимания протокола.
$host = 'api.example.com';
$path = '/data';
$socket = fsockopen($host, 80, $errno, $errstr, 30);
if (!$socket) {
// обработка ошибки подключения
} else {
$request = "GET $path HTTP/1.1\r\n";
$request .= "Host: $host\r\n";
$request .= "Connection: Close\r\n\r\n";
fwrite($socket, $request);
while (!feof($socket)) {
echo fgets($socket, 4096);
}
fclose($socket);
}
Проблема: необходимо корректно завершать заголовки двумя переводами строки, иначе сервер не начнёт передачу данных. Также нужно обрабатывать возможные редиректы и HTTPS (требуется fsockopen через TLS).
Расширенные примеры GET запросов
Пример 1: cURL с полной обработкой ошибок и получением заголовков
$url = 'https://httpbin.org/get';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1); // получать заголовки ответа
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$response = curl_exec($ch);
if ($response === false) {
echo 'Ошибка cURL: ' . curl_error($ch);
} else {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
echo "Заголовки:\n$headers\n\n";
echo "Тело:\n$body\n";
}
curl_close($ch);
Заголовки:
HTTP/1.1 200 OK
Date: Mon, 10 Mar 2025 12:00:00 GMT
Content-Type: application/json
...
Тело:
{
"args": {},
"headers": { ... },
"url": "https://httpbin.org/get"
}
Пример 2: file_get_contents с настройкой User-Agent и тайм-аута
$url = 'https://httpbin.org/user-agent';
$options = [
'http' => [
'method' => 'GET',
'header' => "User-Agent: MyCustomAgent/1.0\r\n",
'timeout' => 2.0 // тайм-аут в секундах
]
];
$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";
}
Ответ: {"user-agent":"MyCustomAgent/1.0"}
Пример 3: fopen построчное чтение больших файлов
$url = 'https://httpbin.org/stream/5';
$handle = fopen($url, 'r');
if ($handle) {
$lineNumber = 1;
while (($line = fgets($handle)) !== false) {
echo "Строка $lineNumber: $line\n";
$lineNumber++;
}
fclose($handle);
} else {
echo "Не удалось открыть URL";
}
Строка 1: {"url":"https://httpbin.org/stream/5","args":{},"headers":{...},"origin":"...","id":0}
Строка 2: {"url":"https://httpbin.org/stream/5","args":{},"headers":{...},"origin":"...","id":1}
...
Пример 4: Сокеты вручную - GET запрос с обработкой редиректа (Location)
$host = 'httpbin.org';
$path = '/redirect/2';
$maxRedirects = 5;
for ($i = 0; $i < $maxRedirects; $i++) {
$socket = fsockopen($host, 80, $errno, $errstr, 10);
if (!$socket) {
die("Ошибка подключения: $errstr ($errno)");
}
$request = "GET $path HTTP/1.1\r\nHost: $host\r\nConnection: close\r\n\r\n";
fwrite($socket, $request);
$response = '';
while (!feof($socket)) {
$response .= fgets($socket, 4096);
}
fclose($socket);
// Парсим статус и заголовки
$lines = explode("\r\n", $response);
$statusLine = $lines[0];
$headers = [];
$bodyStart = false;
foreach ($lines as $line) {
if ($bodyStart) {
$body[] = $line;
} elseif (empty($line)) {
$bodyStart = true;
} else {
$parts = explode(': ', $line, 2);
if (count($parts) == 2) {
$headers[$parts[0]] = $parts[1];
}
}
}
if (isset($headers['Location'])) {
$urlParts = parse_url($headers['Location']);
$host = $urlParts['host'];
$path = $urlParts['path'] . (isset($urlParts['query']) ? '?' . $urlParts['query'] : '');
} else {
echo "Окончательный ответ:\n" . implode("\r\n", $lines) . "\n";
break;
}
}
Окончательный ответ:
HTTP/1.1 200 OK
...
{"args":{},"headers":{...},"origin":"...","url":"http://httpbin.org/get"}
Пример 5: Расширенный cURL с SSL, автоматическими редиректами и прокси
$url = 'https://api.secure.example.com';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // проверка SSL сертификата
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // строгая проверка имени хоста
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // автоматически следовать редиректам
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // максимум редиректов
curl_setopt($ch, CURLOPT_PROXY, 'http://proxy.example.com:8080'); // через прокси
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:pass');
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Ошибка: ' . curl_error($ch);
} else {
$info = curl_getinfo($ch);
echo "HTTP код: {$info['http_code']}\n";
echo "Размер ответа: {$info['size_download']} байт\n";
echo "Содержимое:\n$response\n";
}
curl_close($ch);
HTTP код: 200
Размер ответа: 1234 байт
Содержимое:
{"status":"ok"}