PHP cURL exec: примеры работы с curl_exec

Раздел: PHP -> HTTP запросы с cURL

Библиотека cURL в PHP предоставляет возможность взаимодействовать с различными серверами по протоколам HTTP, HTTPS, FTP и другим. Функция curl_exec выполняет инициализированный ранее сеанс cURL. Правильное использование curl_exec включает настройку параметров, обработку ошибок и освобождение ресурсов. В данной статье рассматриваются основные и продвинутые приемы работы с curl_exec, а также типичные затруднения.

Основные подходы к использованию curl_exec

Наиболее эффективное решение заключается в создании универсальной функции-обёртки. Она принимает URL, метод, данные, заголовки и таймаут, возвращает ответ или информацию об ошибке. Такой подход устраняет дублирование кода и упрощает обработку ошибок.

function curl_request($url, $method = 'GET', $data = null, $headers = [], $timeout = 30) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    if ($method === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    } elseif ($method === 'PUT') {
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    if (!empty($headers)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    }
    $response = curl_exec($ch);
    if (curl_error($ch)) {
        $error = curl_error($ch);
        curl_close($ch);
        return ['error' => $error];
    }
    curl_close($ch);
    return ['response' => $response];
}

Php curl timeout (php curl таймаут)

Функция инициализирует сеанс, устанавливает обязательные опции (возврат ответа, таймаут, проверку SSL), в зависимости от метода настраивает тело запроса и заголовки, затем выполняет запрос. После выполнения проверяется наличие ошибки с помощью curl_error. Если ошибка есть, соединение закрывается и возвращается описание. В противном случае возвращается ответ. Такой подход позволяет безопасно переиспользовать код.

Как выполнить простой GET запрос?

Для получения содержимого страницы по URL достаточно минимальной настройки. Этот вариант подходит для быстрых тестов, но не содержит обработки ошибок.

$ch = curl_init('https://api.example.com/users');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;

Php curl ssl (php curl ssl)

Как отправить POST запрос с данными?

При отправке формы или JSON данных требуется установить опцию CURLOPT_POST и передать данные через CURLOPT_POSTFIELDS. Для форм данные кодируются с помощью http_build_query, для JSON требуется явно указать Content-Type.

$ch = curl_init('https://api.example.com/login');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['username' => 'user', 'password' => 'pass']));
$response = curl_exec($ch);
curl_close($ch);

Php curl ответ (ответ php curl)

Проблема: при передаче массива cURL по умолчанию устанавливает Content-Type multipart/form-data. Для обычных форм это нормально, но для JSON необходимо вручную добавить заголовок.

Как установить пользовательские HTTP заголовки?

Массив заголовков передаётся в CURLOPT_HTTPHEADER. Можно переопределить или добавить любые заголовки.

$headers = [
    'Authorization: Bearer token123',
    'Accept: application/json',
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

Php curl authorization (php curl авторизация)

Ошибка: дублирование стандартных заголовков (например, Host) может привести к конфликту. cURL сам устанавливает обязательные заголовки.

Как работать с куки?

Для сохранения и отправки кук используются CURLOPT_COOKIEFILE и CURLOPT_COOKIEJAR. Указываются пути к файлам, в которые cURL будет записывать и считывать куки.

$ch = curl_init('https://example.com');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/cookies.txt');
$response = curl_exec($ch);
curl_close($ch);

Php curl close (php curl close)

Этот метод подходит для сессионных запросов, когда нужно сохранять аутентификацию между вызовами.

Как использовать прокси-сервер?

Установка опций CURLOPT_PROXY, CURLOPT_PROXYPORT и при необходимости CURLOPT_PROXYUSERPWD позволяет направлять запросы через прокси.

curl_setopt($ch, CURLOPT_PROXY, 'proxy.example.com');
curl_setopt($ch, CURLOPT_PROXYPORT, 8080);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'user:pass');

Php curl cookie (php curl cookie)

Проблема: прокси может требовать аутентификацию; также возможны проблемы с HTTPS – для прокси типа CONNECT необходимо настроить CURLOPT_PROXYTYPE.

Как установить таймаут выполнения?

Таймаут на все операции задаётся через CURLOPT_TIMEOUT, отдельно для соединения – CURLOPT_CONNECTTIMEOUT. Значения указываются в секундах.

curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);

Php curl url (php curl url)

Как обработать ошибки cURL?

После curl_exec вызывается curl_error, которая возвращает текстовое описание последней ошибки. Также можно использовать curl_errno для числового кода.

$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error: ' . curl_error($ch);
} else {
    echo 'Success: ' . $response;
}
curl_close($ch);

Curl exec php (php curl exec)

Необходимо всегда проверять ошибки, чтобы избежать неожиданного поведения.

Как выполнить запрос с проверкой SSL?

По умолчанию cURL проверяет сертификаты. Для отладки проверку можно отключить, но в production рекомендуется использовать CURLOPT_CAINFO с путём к файлу CA bundle.

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ca-certificates.crt');

Curl setopt php (php curl setopt)

Как сделать параллельные запросы (curl_multi)?

Библиотека curl_multi позволяет выполнять несколько запросов одновременно, что ускоряет работу с множеством URL. Инициализируется мульти-обработчик, добавляются отдельные дескрипторы, затем в цикле обрабатываются до завершения всех запросов.

$mh = curl_multi_init();
$ch1 = curl_init('https://api1.com');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch1);
$ch2 = curl_init('https://api2.com');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($mh, $ch2);
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);
echo curl_multi_getcontent($ch1);
echo curl_multi_getcontent($ch2);
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

Этот подход полезен при необходимости загрузить данные с нескольких источников с минимальной задержкой.

Типичные ошибки и способы их устранения

  • SSL certificate problem: возникает при недоверенном сертификате. Для отладки можно установить CURLOPT_SSL_VERIFYPEER в false, но в production лучше указать CURLOPT_CAINFO с актуальным CA bundle.
  • Could not resolve host: проверьте правильность URL и настройки DNS. Убедитесь, что сервер доступен.
  • Timeout: увеличьте значение CURLOPT_TIMEOUT или CURLOPT_CONNECTTIMEOUT. При работе с медленными серверами используйте более высокие значения.
  • Empty reply from server: сервер закрыл соединение без ответа. Проверьте протокол (HTTP vs HTTPS), тело запроса и наличие обязательных заголовков.
  • curl error 28: операция превысила таймаут. Аналогично пункту выше.
  • Проблемы с кодировкой: для сжатых ответов (gzip) установите CURLOPT_ENCODING в пустую строку, чтобы cURL автоматически распаковывал данные.
  • Неверные заголовки: при передаче массива заголовков следите за синтаксисом (формат "Key: Value"). Лишние пробелы или отсутствие двоеточия приведут к ошибке.
- Php curl content (содержимое ответа php curl)
- Php curl init (php curl init)
- Php curl error (ошибки php curl)

Расширенные примеры cURL

Отправка JSON и получение ответа

Пример
$data = json_encode(['name' => 'John', 'email' => 'john@example.com']);
$ch = curl_init('https://jsonplaceholder.typicode.com/posts');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($data)]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
{"id":101,"title":"...","body":"...","userId":1}

Загрузка файла через multipart/form-data

Пример
$file = new CURLFile('/path/to/file.pdf', 'application/pdf', 'document.pdf');
$post = ['file' => $file, 'description' => 'Upload test'];
$ch = curl_init('https://httpbin.org/post');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($ch);
curl_close($ch);
$decoded = json_decode($response, true);
print_r($decoded['files']);
Array ( [file] => Array ( [name] => document.pdf [type] => application/pdf [tmp_name] => ... [error] => 0 [size] => 12345 ) )

Скачивание файла на диск

Пример
$fp = fopen('/tmp/downloaded_file.zip', 'w');
$ch = curl_init('https://example.com/bigfile.zip');
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_exec($ch);
curl_close($ch);
fclose($fp);
echo 'File downloaded';

Авторизация Basic Auth

Пример
$ch = curl_init('https://api.example.com/secure');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
$response = curl_exec($ch);
curl_close($ch);
echo $response;

Параллельные запросы через curl_multi

Пример
$urls = ['https://api1.com', 'https://api2.com', 'https://api3.com'];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $i => $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $handles[$i] = $ch;
}
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);
foreach ($handles as $ch) {
    $response = curl_multi_getcontent($ch);
    echo 'Response: ' . substr($response, 0, 100) . "\n";
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
}
curl_multi_close($mh);
Response: {"data": ...}
Response: {"status": ...}
Response: {"id": ...}

Использование CURLOPT_FOLLOWLOCATION для редиректов

Пример
$ch = curl_init('http://bit.ly/shorturl');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
$response = curl_exec($ch);
$finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
echo 'Final URL: ' . $finalUrl;
curl_close($ch);

Работа с самоподписанным SSL сертификатом

Пример
$ch = curl_init('https://selfsigned.local');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
// Для production рекомендуется указать CA файл
$cert = '/path/to/cacert.pem';
curl_setopt($ch, CURLOPT_CAINFO, $cert);
curl_close($ch);

PHP cURL exec - comments

En
Curl exec php (php)