Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 114 · От первого запроса до полного справочника

cURL: HTTP-интеграции, файлы, параллельные запросы и полный справочник

От одного понятного запроса до multipart, таймаутов, multi и общих кешей: все функции, классы, методы, параметры и константы расширения cURL.

Как читать справочник после первого запроса

Наглядная модель

От данных заказа до результата интеграции

Короткий вызов curl_exec соединяет несколько разных этапов.

  1. Заказ 42 в массиве PHP

    Выбираем форму, JSON или multipart по договору API.

  2. CurlHandle и настройки

    Адрес, тело, заголовки, TLS и таймауты описывают запрос.

  3. Передача и HTTP-ответ

    curl_exec запускает сеть; код HTTP проверяется отдельно от ошибки транспорта.

  4. Проверенный результат

    Разбираем формат, проверяем поля и только потом продолжаем заказ.

Успешная передача ещё не означает успешную бизнес-операцию. Повтор после обрыва может продублировать заказ.

Начните с двух маленьких PHP-файлов: клиент получит строку товара из настоящего ответа. Затем сравните тела формы, JSON и multipart и рассчитайте предложение цены. Здесь сохранён полный справочник cURL: настройка, все семейства констант, объекты, функции, ограничения и версии.

Один CurlHandle
  1. curl_init: объект настроек
  2. curl_setopt: URL, тело, заголовки, сроки
  3. curl_exec: передача и тело
  4. curl_getinfo / curl_error: разные виды результата

Объект клиента можно представить как отдельную карточку настроек и состояния запроса; само наличие такой карточки не означает отправки. Аналогия не описывает соединения и кеши libcurl: reset сбрасывает опции, но не обязан стирать cookies, кеш DNS и живые соединения. Копирование конфигурации также не создаёт независимую бизнес-сессию.

Два запроса: сначала понять цикл диспетчера

Когда нужны два товара, multi управляет несколькими easy-клиентами. Первый задаёт id=1, второй id=2. Диспетчер продвигает передачи и ждёт готовности; приложение отдельно проверяет транспорт каждой передачи, HTTP-статус каждого ответа и его тело. Локальный сервер может обслужить их последовательно: этот опыт не является измерением ускорения.

Один диспетчер и две передачи
  1. CurlHandle №1: /product?id=1
  2. CurlHandle №2: /product?id=2
  3. finishTransfers: exec → сообщения → ожидание select → следующий шаг
  4. Вывод выбранного порядка: Молоток 8; Перчатки 15
Часть помощникаПочему она появилась
function finishTransfers(...): arrayСобственная функция; её аргумент multi — диспетчер, возвращаемое значение — массив завершений.
?callable $tick = nullНеобязательное действие между шагами. В примере pause оно один раз возобновляет приём.
$runningВыходной параметр curl_multi_exec: число незавершённых передач; функция записывает его в переменную.
while (... !== false)Забирает все сообщения завершений; false означает, что очередь сейчас пуста.
hrtime(true)Монотонное время в наносекундах. Общий предел 5 секунд ограничивает цикл, а не заменяет таймаут каждого клиента.
curl_multi_selectОжидание события вместо непрерывного холостого вызова exec. При ошибке цикл прекращается; нулевой результат получает короткую паузу.

Полный multi-loop.php. Он входит в каждый архив multi. Это вспомогательная часть урока, а не новая встроенная функция PHP.

<?php
function finishTransfers(CurlMultiHandle $multi, ?callable $tick = null): array {
    $messages = [];
    $deadline = hrtime(true) + 5_000_000_000;
    do {
        $state = curl_multi_exec($multi, $running);
        if ($state !== CURLM_OK) { throw new RuntimeException(curl_multi_strerror($state)); }
        if ($tick !== null) { $tick(); }
        while (($message = curl_multi_info_read($multi)) !== false) {
            $messages[] = $message;
        }
        if (hrtime(true) > $deadline) { throw new RuntimeException('Общий срок ожидания истёк'); }
        if ($running > 0) {
            $ready = curl_multi_select($multi, 0.1);
            if ($ready < 0) { throw new RuntimeException('Ошибка ожидания multi'); }
            if ($ready === 0) { usleep(1000); }
        }
    } while ($running > 0);
    return $messages;
}

Теперь полный пример curl_multi_init создаёт клиентов, подключает этот файл и показывает обе строки. curl_pause добавляет callback: при первом фрагменте он возвращает PAUSE, не записав байты; при повторном получает тот же фрагмент и сохраняет его ровно один раз. Освобождением состояния и ограничением размера ответа нельзя пренебрегать в длительно работающем процессе.

Зачем серверу PHP собственный HTTP-клиент

Магазин получил заказ, теперь нужно передать его доставке или получить статус оплаты. Браузер посетителя не обязан выполнять этот обмен: PHP сам обращается к серверу партнёра, получает ответ и продолжает работу. cURL — расширение PHP поверх библиотеки libcurl; отдельная консольная программа curl и PHP-расширение устанавливаются и проверяются отдельно.

Два запроса, два разных участника
  1. Браузер → наш PHP: оформить заказ42
  2. Наш PHP → API доставки: подготовить отправление
  3. API → PHP: статус и данные ответа
  4. PHP проверяет их → показывает результат посетителю

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Начнём с подготовки, которая вообще не требует Интернета. $handle — имя переменной, = сохраняет значение, круглые скобки содержат аргумент функции; строка в кавычках здесь является адресом. Настройка не равна выполнению запроса.

Этот вариант. example.invalid — зарезервированное демонстрационное имя. В этом примере нет curl_exec, поэтому адрес не запрашивается. Проверка false объяснена отдельно в карточке curl_init.

Создать клиента и посмотреть настроенный адресСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init('https://example.invalid/orders');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
echo curl_getinfo($handle, CURLINFO_EFFECTIVE_URL), "\n";
Ожидаемый результат
https://example.invalid/orders

libcurl поддерживает не только HTTP/HTTPS: в зависимости от сборки есть FTP, Gopher, Telnet, DICT, локальные file, LDAP и другие протоколы. В библиотеке предусмотрены сертификаты HTTPS, POST/PUT, отправка форм и файлов, proxy, cookies, логин/пароль. Наличие каждой возможности проверяют через curl_version. PHP-расширение FTP — другой интерфейс, а SFTP не является FTP поверх HTTPS.

Для приложения можно скрыть повторяемую настройку за классом клиента или использовать Guzzle через Composer. Тогда понятный метод вроде listMethod($parameters, $method) остаётся на прикладном уровне; под ним всё равно нужны правильный формат данных, обработка отказов и ограничения. Практика клиента API и Зачем здесь объект.

Проверить именно тот PHP, который выполняет приложение

Ошибка «undefined function curl_init» означает, что текущий процесс PHP не предоставил эту функцию. Установленная программа curl в терминале этого не исправляет. CLI, Apache и FPM могут читать разные php.ini; сначала найдите используемый интерпретатор и его конфигурацию, затем подключайте подходящее расширение.

Найти причину, не переставляя всё подряд
  1. Какой PHP запускает приложение?
  2. php --ini и php -m для CLI
  3. Для веб-процесса проверяем его SAPI/config
  4. После настройки перезапускаем нужный процесс

Этот вариант. Таков результат проверенной сборки PHP8.5.11/libcurl8.22.0. В другой сборке false — диагностический результат, а не повод отключить проверки сертификата. php_ini_loaded_file показывает путь локальной конфигурации; не публикуйте подробную диагностику сервера для посетителей.

Проверка возможностей без HTTP-запросаСамостоятельный пример
<?php
declare(strict_types=1);

var_dump(extension_loaded('curl'));
var_dump(function_exists('curl_init'));
$version = curl_version();
if ($version === false) { throw new RuntimeException('No libcurl version'); }
var_dump(in_array('https', $version['protocols'], true));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

В консоли полезны php --ini, php -m, php --ri curl. На Linux пакет расширения должен соответствовать версии и источнику установки PHP. На Windows DLL должна совпадать с ABI PHP, архитектурой и TS/NTS; включение обычно делается через extension=curl и корректный extension_dir. Команды установки конкретного дистрибутива отличаются — нельзя заменять ими проверку текущего процесса.

При сборке PHP из исходников требуется libcurl и параметр --with-curl; подробности ниже сохраняют официальный договор установки. Для уже готовой сборки не требуется автоматически пересобирать весь PHP.

Требования libcurl и исторические границы

Версия PHP не равна версии libcurl
  1. PHP предоставляет функции curl_*
  2. libcurl реализует протоколы и опции
  3. TLS выполняет выбранный backend
  4. Проверяем все уровни нужной возможности
Ветка PHPМинимум libcurl из официального руководства
Ранее PHP7.37.10.5
PHP7.3+7.15.5
PHP8.0+7.29.0
PHP8.4+7.61.0

Это нижняя граница сборки соответствующей ветки, а не рекомендация устанавливать устаревшую библиотеку. Конкретные новые опции требуют более позднего libcurl; одна версия PHP не гарантирует их доступность. curl_version сообщает версию, protocols и feature flags. В проверенном окружении libcurl8.22.0, OpenSSL3.5.8, zlib1.3.2; эти числа описывают стенд, не объявляют его единственно возможной конфигурацией.

Установка: готовый пакет и сборка из исходников

Согласованный комплект
  1. PHP нужной архитектуры/ABI
  2. Расширение curl из того же комплекта
  3. Зависимые библиотеки доступны процессу
  4. Проверка startup diagnostics + extension_loaded

Официальная инструкция для сборки использует --with-curl[=DIR]: в DIR находятся include и lib, заголовки curl/easy.h и curl/curl.h, библиотека libcurl.a. Набор файлов и параметры современного сборочного окружения могут различаться; используйте процедуру для выбранной ветки PHP, а не произвольную смесь SDK.

На Windows руководство перечисляет SSL-зависимости: старые libeay32.dll/ssleay32.dll либо, начиная сOpenSSL1.1, libcrypto-*.dll/libssl-*.dll, а также libssh2.dll, доступные через окружение процесса. Современный комплект может содержать другой набор зависимостей. Не скачивайте случайные одноимённые DLL в System32: используйте комплект своей сборки PHP. Отдельная libcurl.dll с сайта cURL по этой инструкции не требуется.

После редактирования правильного php.ini перезапустите именно тот веб-процесс, который загружает модуль. Успех CLI не доказывает успех FPM и наоборот. «Модуль не найден» при существующем php_curl.dll может относиться к его зависимости; проверяйте журнал запуска.

curl.cainfo и проверка HTTPS

Почему недостаточно получить какие-то байты
  1. Сервис предъявляет сертификат
  2. Клиент проверяет доверенную цепочку и имя
  3. Настроенный CA bundle участвует в проверке
  4. Только затем передаём чувствительные данные
НастройкаДоговор
curl.cainfostring, по умолчанию NULL, режим INI_SYSTEM. Значение по умолчанию для CURLOPT_CAINFO; путь к CA-файлу должен быть абсолютным.
CURLOPT_CAINFOМожно явно задать для конкретного handle; доверенный актуальный bundle, доступный процессу. Поддержка и default store зависят от TLS backend/libcurl.
CURLOPT_SSL_VERIFYPEER / VERIFYHOSTПроверка цепочки и соответствия имени выполняют разные задачи. Для обычного HTTPS сохраняют peer=true и host=2.

Этот вариант. Пример выполняется отдельным CLI-процессом и не меняет файлы конфигурации. Для per-request CA используйте CURLOPT_CAINFO с существующим абсолютным путём; бессмысленный путь выше демонстрирует только режим INI_SYSTEM.

Убедиться, что системную настройку нельзя менять обычным ini_setСамостоятельный пример
<?php
declare(strict_types=1);

$before = ini_get('curl.cainfo');
var_dump(ini_set('curl.cainfo', 'not-a-real-ca.pem') === false);
var_dump(ini_get('curl.cainfo') === $before);
Ожидаемый результат
bool(true)
bool(true)

Ошибка проверки сертификата требует выяснить, верны ли часы, hostname, цепочка сервера и trust store клиента. Отключение VERIFYPEER/VERIFYHOST не исправляет доверие и не подходит для примера с токенами. CURLOPT_CAINFO не загружает bundle автоматически. openssl.cafile относится к другому слою PHP и не является универсальной заменой curl.cainfo.

От resource к объектам: что изменилось в PHP8

Типы отражают роль
  1. Один запрос → CurlHandle
  2. Координация запросов → CurlMultiHandle
  3. Обмен кэшами → CurlShareHandle
  4. СPHP8.5 persistent share → отдельный класс

До PHP8 расширение возвращало три типа ресурсов: curl, curl_multi и curl_share handles. Начиная с8.0 соответствующие значения — объекты. Поэтому старая проверка is_resource($handle) может ошибочно считать рабочий клиент неверным. CurlSharePersistentHandle добавлен позднее, сPHP8.5, и не подменяет обычный share во всех операциях.

Этот вариант. Замена типа не превращает handle в HTTP-ответ. Нужна явная операция выполнения и проверка её результата. curl_close сPHP8 ничего не делает и с8.5 deprecated; multi_close имеет другое назначение, не переносите правило механически.

Распознать современный handleСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
var_dump(is_resource($handle), $handle instanceof CurlHandle);
Ожидаемый результат
bool(false)
bool(true)

curl_multi_init, curl_share_init и curl_share_init_persistent показывают создание соответствующих объектов.

CurlHandle: настройки и состояние одного клиента

CurlHandle — непрозрачный final-класс сPHP8. Его создаёт curl_init; у него нет публичного конструктора, прикладных свойств и методов. Управление идёт функциями curl_*, принимающими объект первым аргументом. «Непрозрачный» означает, что внутренние поля библиотеки не являются вашим публичным API.

Объект не является массивом настроек
  1. curl_init → $handle
  2. curl_setopt($handle, ...) меняет настройки
  3. curl_exec($handle) использует их
  4. curl_getinfo($handle, ...) читает сведения

Этот вариант. Два имени переменных указывают на один объект. Отдельную конфигурацию создают curl_copy_handle или clone, а не обычным присваиванием.

Обычное присваивание сохраняет тот же handleСамостоятельный пример
<?php
declare(strict_types=1);

$first = curl_init('https://example.invalid/first');
if ($first === false) { throw new RuntimeException('cURL unavailable'); }
$same = $first;
curl_setopt($same, CURLOPT_URL, 'https://example.invalid/second');
echo curl_getinfo($first, CURLINFO_EFFECTIVE_URL), "\n";
Ожидаемый результат
https://example.invalid/second

Этот вариант. Эти действия выполнены наPHP8.5.11. clone создаёт копию настроек, но не обещает снимок текущей передачи или независимость всех callback-объектов. Прикладной token храните в своём клиенте/конфигурации, не в произвольном поле CurlHandle.

Проверить границы непрозрачного объектаСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$copy = clone $handle;
var_dump($copy instanceof CurlHandle, $copy === $handle);
try { new CurlHandle(); } catch (Error $error) { echo "factory required\n"; }
try { serialize($handle); } catch (Exception $error) { echo "not serializable\n"; }
try { $handle->token = 'demo'; } catch (Error $error) { echo "no dynamic properties\n"; }
Ожидаемый результат
bool(true)
bool(false)
factory required
not serializable
no dynamic properties

Три основных сценария: форма, JSON и файл ответа

Получатель задаёт формат. Если endpoint принимает HTML-подобную форму, тело кодируется через http_build_query; если ожидает JSON, нужен json_encode и соответствующий Content-Type. Массив PHP нельзя считать уже готовым JSON. HTTP-ответ проверяется после transport-ошибок, а структура данных — после декодирования.

Один заказ, разные договоры
  1. PHP: order=42, city=Perm
  2. Форма → order=42&city=Perm; JSON → объект
  3. curl_exec доставляет байты в выбранный endpoint
  4. Ответ → HTTP200 → декодирование → проверка полей

Этот вариант. Локальный /form разбирает form-urlencoded и возвращает разобранные поля JSON. Число42 в форме стало строкой. На реальном PHP-приёмнике это обычный $_POST; тип/диапазон проверяет приложение. В архиве приложен http-fixture.py: запустите python http-fixture.py в отдельном терминале, а клиенту задайте переменную окружения PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8772 способом своей оболочки. Сервер слушает только loopback; после опыта остановите его Ctrl+C.

Передать заказ обычной формойПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if (!is_string($base) || $base === '') { throw new RuntimeException('Start the local HTTP fixture'); }
$handle = curl_init($base . '/form');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$data = ['order' => 42, 'city' => 'Perm'];
if (!curl_setopt_array($handle, [
    CURLOPT_POSTFIELDS => http_build_query($data, '', '&'),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT_MS => 3000,
    CURLOPT_PROXY => '',
])) { throw new RuntimeException('Cannot configure client'); }
$response = curl_exec($handle);
if ($response === false) { throw new RuntimeException(curl_error($handle)); }
if (curl_getinfo($handle, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Unexpected HTTP status'); }
$received = json_decode($response, true, flags: JSON_THROW_ON_ERROR);
if (!is_array($received) || !isset($received['order'], $received['city'])) { throw new RuntimeException('Unexpected response'); }
echo $received['order'], ':', $received['city'], "\n";
var_dump(is_string($received['order']));
Ожидаемый результат
42:Perm
bool(true)

Этот вариант. Локальный /json возвращает разобранное тело JSON: число осталось числом. У PHP-приёмника JSON сам по себе не наполняет $_POST: читают php://input и явно декодируют. Заголовок без json_encode не меняет формат массива. В архиве приложен http-fixture.py: запустите python http-fixture.py в отдельном терминале, а клиенту задайте переменную окружения PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8772 способом своей оболочки. Сервер слушает только loopback; после опыта остановите его Ctrl+C.

Передать числовое поле через JSONПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if (!is_string($base) || $base === '') { throw new RuntimeException('Start the local HTTP fixture'); }
$body = json_encode(['order' => 42, 'city' => 'Perm'], JSON_THROW_ON_ERROR);
$handle = curl_init($base . '/json');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
if (!curl_setopt_array($handle, [
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT_MS => 3000,
    CURLOPT_PROXY => '',
])) { throw new RuntimeException('Cannot configure client'); }
$response = curl_exec($handle);
if ($response === false) { throw new RuntimeException(curl_error($handle)); }
if (curl_getinfo($handle, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Unexpected HTTP status'); }
$received = json_decode($response, true, flags: JSON_THROW_ON_ERROR);
if (!is_array($received) || !isset($received['order'], $received['city'])) { throw new RuntimeException('Unexpected response'); }
echo $received['order'], ':', $received['city'], "\n";
var_dump(is_int($received['order']));
Ожидаемый результат
42:Perm
bool(true)

Этот вариант. Тело идёт в поток, а не целиком в строку PHP. Ошибку нельзя дописывать в файл данных: потребитель получит повреждённый документ. В реальном скачивании дополнительно ограничьте объём, проверьте формат и только затем атомарно заменяйте конечный файл. Временный файл удаляется после закрытия. В архиве приложен http-fixture.py: запустите python http-fixture.py в отдельном терминале, а клиенту задайте переменную окружения PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8772 способом своей оболочки. Сервер слушает только loopback; после опыта остановите его Ctrl+C.

Сохранить тело ответа в отдельный потокПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if (!is_string($base) || $base === '') { throw new RuntimeException('Start the local HTTP fixture'); }
$output = tmpfile();
if ($output === false) { throw new RuntimeException('Cannot create temporary file'); }
$handle = curl_init($base . '/ok');
if ($handle === false) { fclose($output); throw new RuntimeException('cURL unavailable'); }
try {
    if (!curl_setopt_array($handle, [CURLOPT_FILE => $output, CURLOPT_TIMEOUT_MS => 3000, CURLOPT_PROXY => ''])) {
        throw new RuntimeException('Cannot configure download');
    }
    if (curl_exec($handle) === false) { throw new RuntimeException(curl_error($handle)); }
    if (curl_getinfo($handle, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Unexpected HTTP status'); }
    rewind($output);
    echo stream_get_contents($output);
} finally { unset($handle); fclose($output); }
Ожидаемый результат
READY

Выбор подхода, стоимость и отказ зависимости

Полезный ответ проходит несколько проверок
  1. Транспорт: curl_exec !== false
  2. HTTP: ожидаемый код, не просто любой200
  3. Формат: JSON/файл по договору
  4. Предметная область: заказ42 действительно принят
ЗадачаПодход
Один небольшой запросcurl_exec с timeout и проверкой ответа.
Несколько независимых источниковcurl_multi_exec с ограничением параллельности и обработкой каждой завершённой передачи.
Повторные обращенияПереиспользовать клиент осознанно; кэши могут ускорить соединение, но cookies/авторизация не должны смешивать пользователей.
Вложение на дискеCURLFile::__construct; заранее читать всё в память не требуется.
Небольшой отчёт уже в переменнойCURLStringFile::__construct.
Простой краткий HTTP readPHP stream context тоже возможен; cURL даёт подробные опции/метрики, готовая библиотека — удобный уровень приложения.

Обычно время уходит на DNS, соединение, TLS и ожидание сервера, а не на вызов curl_setopt. Бесконечный timeout и неограниченный ответ удерживают PHP-worker и память. RETURNTRANSFER собирает тело в строку; поток/WRITEFUNCTION помогают контролировать накопление. Multi не создаёт автоматически безопасную очередь на тысячу запросов: ограничивайте нагрузку и количество соединений.

Повтор POST после обрыва может создать второй заказ: удалённый сервер мог выполнить операцию до потери ответа. Следуйте договору idempotency key, Retry-After и максимальному числу попыток; не повторяйте любой отказ вслепую. Токен и исходное тело не должны целиком попадать в журнал. Полученный HTTP404/429/500 и curl_errno описывают разные уровни.

Для URL, на который влияет посетитель, нужны политика разрешённых узлов/протоколов, проверка редиректов, сетевые ограничения и защита от SSRF. Одна проверка строки или filter_var не гарантирует безопасное назначение после DNS и перенаправления. Учебный loopback-стенд намеренно локальный и не является шаблоном разрешения пользовательских URL.

Практика: объяснить путь заказа до сервиса

Возьмите форму и JSON из предыдущего раздела. До запуска предскажите тип order после приёма. Затем измените имя поля city на destination на обеих сторонах и проверьте отказ, если изменить только одну. Объясните отдельно, что произойдёт при404, пустом ответе и невалидномJSON; эти случаи не заменяют друг друга.

Критерий понимания
  1. Могу показать место выбора формата
  2. Знаю, где происходит сеть
  3. Различаю transport, HTTP и данные
  4. Могу обработать отказ без второго заказа

Этот вариант. Это локальная проверка соглашений форматов, не замена HTTP-тесту. Следующий шаг: обернуть проверенный обмен в метод своего клиента, возвращающий понятные приложению данные. От cURL к клиенту сервиса.

Сравнить формы данных ещё до сетевого запросаСамостоятельный пример
<?php
declare(strict_types=1);

$order = ['order' => 42, 'city' => 'Perm'];
parse_str(http_build_query($order, '', '&'), $form);
$json = json_decode(json_encode($order, JSON_THROW_ON_ERROR), true, flags: JSON_THROW_ON_ERROR);
var_dump($form['order'] === '42', $json['order'] === 42);
Ожидаемый результат
bool(true)
bool(true)

CURLFile: описание файла и три публичных свойства

Приложить акт к заказу — это не прочитать его в переменную и не выбрать файл в браузере. CURLFile хранит описание серверного источника для будущего запроса; без curl_exec ни один байт не уйдёт к партнёру.

Путь источника, имя поля и имя вложения
  1. $file->name = storage/act.txt
  2. $file->mime = text/plain; postname = act-42.txt
  3. POSTFIELDS[document] = $file
  4. PHP-приёмник: $_FILES[document][name] = act-42.txt
СвойствоСмысл
public string name = ""Исходный путь. Конструктор получает его первым аргументом.
public string mime = ""Заданный тип; пустой → application/octet-stream при передаче.
public string postname = ""Заданное внешнее имя; пустой → name при передаче.

Этот вариант. Здесь свойства отображают конфигурацию. Изменяйте её до установки POSTFIELDS. Getter не обращается к сети.

Сопоставить свойства и getter-методыСамостоятельный пример
<?php
declare(strict_types=1);

$file = new CURLFile('act.txt', 'text/plain', 'act-42.txt');
var_dump($file->name === $file->getFilename());
var_dump($file->mime === $file->getMimeType());
var_dump($file->postname === $file->getPostFilename());
Ожидаемый результат
bool(true)
bool(true)
bool(true)

CURLFile сPHP5.5 допускает наследование, в отличие от final-класса CurlHandle. Клонировать описание можно; сериализовать нельзя с7.4, unserialize тоже не поддерживается. Для отложенной задачи храните проверенный идентификатор документа и создавайте описание заново при выполнении. CURLFile::__construct и процедурная форма curl_file_create.

CURLStringFile: готовое содержимое вместо пути

Отчёт иногда уже собран в переменной. CURLStringFile сPHP8.1 позволяет представить эти байты файловой частью multipart без промежуточной записи на диск. Это экономит отдельную операцию с диском, но не память под сам отчёт.

Содержимое уже есть
  1. $data содержит байты A, NUL, B
  2. CURLStringFile(data, payload.bin)
  3. Свойства data/postname/mime
  4. cURL формирует файловую часть с этими байтами
СвойствоСмысл
public string dataБайты отчёта. Значение требует инициализации конструктором.
public string postnameИмя файла в multipart.
public string mimeТип; конструктор по умолчанию ставит application/octet-stream.

Этот вариант. Получатель получит семь букв act.txt, а не содержимое одноимённого файла. Если нужен файл на диске, выбирайте CURLFile.

Убедиться, что путь не читается автоматическиСамостоятельный пример
<?php
declare(strict_types=1);

$file = new CURLStringFile('act.txt', 'attachment.txt', 'text/plain');
echo $file->data, "\n";
echo strlen($file->data), "\n";
Ожидаемый результат
act.txt
7

У класса только конструктор, свойства публичные; это не подкласс CURLFile. В PHP8.5.11 clone и обычная сериализация поддерживаются, но сериализованный объект содержит сам документ: не размещайте его в журнале и не принимайте unserialize от недоверенного клиента. Для задания в очереди обычно лучше явно хранить договорённые данные. CURLStringFile::__construct.

Несколько запросов: CurlMultiHandle и цикл передачи

Витрина получает цену и остаток независимо. Последовательные запросы тратят время на ожидание каждого сервиса; multi позволяет продвигать оба запроса в одном цикле. Это полезно только для независимых операций: запрос «оплатить» нельзя делать раньше ответа «создать заказ». Сам multi не добавляет ретраи, очередь заданий или безопасное повторение POST.

Кто кого вызывает
  1. Ваш PHP-код создаёт два easyhandle
  2. Multi хранит оба клиента
  3. exec продвигает ввод/вывод; select ожидает активность
  4. info_read сообщает завершения; getcontent получает нужное тело

CurlMultiHandle — final непрозрачный класс PHP8+, замена прежнего resource. Создавайте его через curl_multi_init, не через new. У него нет пользовательских полей/методов для ручного изменения состояния. Ссылка в переменной — доступ к тому же диспетчеру; клонирование и сериализация не поддерживаются. Для PHP8.2 список клиентов храните отдельно; PHP8.5 добавил get_handles.

МеханизмДля чего
EasyhandleНастройки и результат одного запроса.
MultihandleСовместное продвижение нескольких передач.
SharehandleОбщие кеши между клиентами; самостоятельно передачи не запускает.

Порядок завершения может отличаться от порядка URL. Привязывайте результат к объекту или своей метке, а не позиции сообщения в очереди. Одновременно ограничивайте число задач приложения, соединения, размер ответов и таймаут каждого запроса. Для ограничений частоты см. лимиты API.

CurlShareHandle: общие кеши и границы пользователей

Сайт выполняет два запроса партнёру от имени одного пользователя. В первом приходит cookie, второй должен отправить её обратно. Обычный sharehandle объединяет выбранный кеш между двумя easy-клиентами. Он не копирует автоматически всю конфигурацию и не запускает запросы параллельно.

Общее состояние — выбранный кеш
  1. Создать share
  2. Выбрать COOKIE для одного пользователя
  3. Подключить к первому и второму easyhandle
  4. Cookie первого становится доступна второму по правилам домена/пути

CurlShareHandle — final непрозрачный класс PHP8+, замена resource. Его создаёт curl_share_init; new, clone и serialize не поддерживаются. Поля вручную не заполняют. Share удерживается подключёнными easyhandle; unset одной переменной не означает уничтожения объекта. curl_share_close с PHP8 ничего не делает и deprecated с8.5.

НеобходимостьВыбор
Один клиент подряд делает несколько запросовЧасто достаточно повторно использовать easyhandle.
Два easyhandle одной пользовательской операцииОбычный share с нужной категорией, включая cookies при одном пользователе.
Кеши между PHP-запросамиPersistent share8.5+ без cookies, с отдельными границами процесса.

CurlSharePersistentHandle: что переживает PHP-запрос

В живущем PHP-воркере повторные интеграции могут использовать DNS/TLS/connection кеш, оставшийся от прежнего запроса. PHP8.5 предоставляет отдельную фабрику curl_share_init_persistent. Кеш не становится общей базой всех процессов; перезапуск воркера заканчивает его жизнь.

Запросы внутри одного воркера
  1. Запрос A выбирает набор DNS+CONNECT
  2. Underlying share хранится в процессе
  3. Запрос B того же процесса выбирает тот же набор
  4. Повторно используется кеш, но не PHP-переменные A

Final класс имеет одно публичное readonly array свойство options — нормализованный набор категорий. Readonly означает запрет переприсваивания/изменения этого массива через свойство. Создание только фабрикой, без new; clone/serialize не поддерживаются. Это не подкласс CurlShareHandle; старые share_* функции настройки/диагностики его не принимают. CURLOPT_SHARE принимает оба вида.

Не путайте кеш соединений с обещанием обязательного reuse: пригодность соединения, протокол, адрес, TLS-параметры, закрытие сервером и политика libcurl влияют на выбор. Одинаковый набор options не является гарантией одинакового PHP-объекта или одинакового соединения. Cookies запрещены самим API, чтобы не смешивать пользователей.

Практика: цена, остаток и HTTP-ошибка в одном наборе

В локальном стенде /stock возвращает {"qty":7}, /price — {"kopecks":450}, а /missing — HTTP404 и JSON с описанием. Нужно собрать карточку товара, не перепутав ошибку сети, статус HTTP и неправильные поля. Массив результатов связывается с меткой запроса, поэтому не зависит от порядка завершения.

CURLOPT_PRIVATE хранит вашу метку в easyhandle и не отправляет её серверу; CURLINFO_PRIVATE читает её обратно. CURLOPT_RETURNTRANSFER собирает тело в строку. JSON разбирается через json_decode, а is_int проверяет ожидаемые целые поля. Оператор ?? даёт null при отсутствии поля. JSON и проверка полей; Транспортная и HTTP-ошибка.

В комплекте примера есть fixture-server.py. Запустите его установленным Python 3: python fixture-server.py; по умолчанию он слушает только127.0.0.1:8010. В другом терминале задайте PHPMAN_CURL_TEST_BASE=http://127.0.0.1:8010 для процесса PHP и выполните example.php. Сервер заканчивают Ctrl+C. Это учебное окружение, не установка публичного веб-сервера.

Цена и остаток проверяются независимо
  1. Создать 3 клиента с метками stock/price/missing
  2. exec/select продвигают запросы, максимум 2 соединения
  3. info_read → CURLE_OK отдельно от HTTP 200/404
  4. Проверить JSON/типы цены и остатка; собрать карточку

Этот вариант. Контекст: включён curl, запущен приложенный локальный fixture-сервер, PHPMAN_CURL_TEST_BASE задаёт его адрес. Общий CLI-check выполняет lint; отдельный evidence-стенд реально выполняет запросы и проверяет этот вывод. Отключение proxy относится к loopback-тесту. Внешние адреса не подставляются, авторизация/ретраи/политика загрузки больших тел здесь не реализованы.

Собрать результаты собственного HTTP-стендаПример для указанного окружения
<?php
$base = getenv('PHPMAN_CURL_TEST_BASE');
if ($base === false || !str_starts_with($base, 'http://127.0.0.1:')) {
    throw new RuntimeException('Start the local fixture server first');
}
$multi = curl_multi_init();
curl_multi_setopt($multi, CURLMOPT_MAX_TOTAL_CONNECTIONS, 2);
$results = [];
try {
    foreach (['stock', 'price', 'missing'] as $name) {
        $handle = curl_init($base . '/' . $name);
        if ($handle === false) { throw new RuntimeException('Client unavailable'); }
        curl_setopt_array($handle, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_PRIVATE => $name,
            CURLOPT_CONNECTTIMEOUT_MS => 1000,
            CURLOPT_TIMEOUT_MS => 2000,
            CURLOPT_PROXY => '',
        ]);
        if (curl_multi_add_handle($multi, $handle) !== CURLM_OK) {
            throw new RuntimeException('Add failed');
        }
    }
    do {
        $status = curl_multi_exec($multi, $running);
        if ($status !== CURLM_OK) { throw new RuntimeException(curl_multi_strerror($status)); }
        while (($info = curl_multi_info_read($multi)) !== false) {
            $handle = $info['handle'];
            $name = curl_getinfo($handle, CURLINFO_PRIVATE);
            if ($info['result'] !== CURLE_OK) { throw new RuntimeException('Transport failed: ' . $name); }
            $http = curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
            $body = curl_multi_getcontent($handle);
            $data = json_decode($body, true, 16, JSON_THROW_ON_ERROR);
            $results[$name] = ['http' => $http, 'data' => $data];
            curl_multi_remove_handle($multi, $handle);
        }
        if ($running > 0) {
            $ready = curl_multi_select($multi, 0.1);
            if ($ready === -1) { throw new RuntimeException('Wait failed'); }
            if ($ready === 0) { usleep(1000); }
        }
    } while ($running > 0);
} finally { curl_multi_close($multi); }
if ($results['stock']['http'] !== 200 || !is_int($results['stock']['data']['qty'] ?? null)) {
    throw new RuntimeException('Invalid stock document');
}
if ($results['price']['http'] !== 200 || !is_int($results['price']['data']['kopecks'] ?? null)) {
    throw new RuntimeException('Invalid price document');
}
echo 'Stock: ', $results['stock']['data']['qty'], "\n";
echo 'Price: ', $results['price']['data']['kopecks'], "\n";
echo 'Missing HTTP: ', $results['missing']['http'], "\n";
Ожидаемый результат
Stock: 7
Price: 450
Missing HTTP: 404

CURLE_OK у /missing означает, что HTTP-ответ получен; бизнес-операция всё равно неуспешна из-за404. Для больших ответов используйте ограничивающий WRITEFUNCTION/файл, потому что RETURNTRANSFER собирает каждое тело целиком. Таймауты относятся к клиентам; лимит соединений не ограничивает частоту вызовов партнёра.

Практика: cookie-сессия между двумя клиентами

Два запроса одного учебного пользователя: /set-cookie выставляет демонстрационную cookie, /read-cookie возвращает её значение. Каждый запрос создаёт новый easyhandle, но оба подключены к одному обычному share. Это позволяет сохранить состояние интеграции без cookie-файла на диске.

Cookie переходит через общий кеш
  1. Первый клиент получает Set-Cookie
  2. libcurl сохраняет cookie в обычном share
  3. Второй клиент использует тот же share и домен
  4. Сервер видит demo_session=demo-only

Этот вариант. Это реальный loopback HTTP-тест, а не обращение к аккаунту или внешнему сервису. До кода нужен приложенный fixture-server.py, запущенный Python 3, и PHPMAN_CURL_TEST_BASE по инструкции предыдущего раздела. Для нового пользователя создают отдельный share; persistent-API cookies не принимает.

Проверить общий cookie-кеш на своём сервереПример для указанного окружения
<?php
$base = getenv('PHPMAN_CURL_TEST_BASE');
if ($base === false || !str_starts_with($base, 'http://127.0.0.1:')) {
    throw new RuntimeException('Start the local fixture server first');
}
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) {
    throw new RuntimeException('Cookie share unavailable');
}
foreach (['set-cookie', 'read-cookie'] as $route) {
    $handle = curl_init($base . '/' . $route);
    if ($handle === false) { throw new RuntimeException('Client unavailable'); }
    curl_setopt_array($handle, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SHARE => $share,
        CURLOPT_COOKIEFILE => '',
        CURLOPT_CONNECTTIMEOUT_MS => 1000,
        CURLOPT_TIMEOUT_MS => 2000,
        CURLOPT_PROXY => '',
    ]);
    $body = curl_exec($handle);
    if ($body === false || curl_getinfo($handle, CURLINFO_RESPONSE_CODE) !== 200) {
        throw new RuntimeException('Fixture request failed');
    }
    echo $body, "\n";
    unset($handle);
}
Ожидаемый результат
cookie-set
demo-only

Cookie domain/path/expiry продолжают действовать: общий кеш не заставляет отправлять cookie чужому домену. Продакшен-интеграция использует HTTPS и проверку сертификата; для простого локального транспорта здесь выбран HTTP на127.0.0.1. Сам share не является логином, авторизацией или сессией сайта PHP.

Как читать и выбирать константы cURL

Представьте бланк доставки: адрес, способ отправки и предел ожидания — разные поля. CURLOPT_* выбирает поле; значение справа заполняет его. CURLINFO_* обычно читает результат; CURLE_* обозначает ошибку. Все сами константы имеют тип int, однако значение настройки может быть строкой, bool, массивом, ресурсом или callback. Нельзя подставить целочисленный код из другого семейства только потому, что тип совпадает.

ЗаписьКак прочитать
curl_setopt($h, CURLOPT_TIMEOUT_MS, 1500)Клиенту $h задать общий предел 1500 миллисекунд.
curl_getinfo($h, CURLINFO_RESPONSE_CODE)Прочитать код последнего ответа; это не установка опции.
CURLAUTH_BASIC | CURLAUTH_DIGESTПобитовое | объединяет разрешённые методы в маску. Оно допустимо только там, где договор действительно требует маску.
($features & CURL_VERSION_HTTP2) !== 0Побитовое & оставляет нужный бит; сравнение с 0 проверяет наличие возможности.
defined('CURLOPT_PROTOCOLS_STR')Проверить существование имени до обращения к константе; строка здесь необходима.
Проверка доступности настройки до запроса
  1. Имя CURLOPT_TIMEOUT_MS передаётся строкой в defined
  2. true → можно использовать именованный ключ
  3. curl_setopt настраивает handle
  4. Передача начнётся только отдельным curl_exec

Этот вариант. constant получает значение по проверенному имени. В обычном коде пишите непосредственно CURLOPT_TIMEOUT_MS: динамическое имя нужно здесь лишь для объяснения разницы. Существование имени не доказывает поддержку HTTP/3, TLS backend или отдельного протокола.

Отличить имя настройки от её значенияСамостоятельный пример
<?php
declare(strict_types=1);

$name = 'CURLOPT_TIMEOUT_MS';
if (!defined($name)) throw new RuntimeException('Нужна более новая сборка cURL');
$option = constant($name);
echo is_int($option) ? "Ключ настройки — целое число\n" : "Неожиданный тип\n";
$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
if (!curl_setopt($handle, $option, 1500)) throw new RuntimeException('Настройка отклонена');
echo "Значение — 1500 миллисекунд; запрос не отправлен\n";
Ожидаемый результат
Ключ настройки — целое число
Значение — 1500 миллисекунд; запрос не отправлен

У констант ниже указаны назначение, договор значения/результата, default для настроек и известные версии. Default относится к новому handle, до изменения и до прикладной политики. PHP местами задаёт собственные defaults поверх libcurl. Версия PHP, версия libcurl и включённые при сборке backend — три независимых условия; документация новых native API не означает, что PHP экспортирует их все. У старых имён отдельно сохранён статус alias/deprecated/removed.

Выберите задачу: Адрес и допустимые протоколы; HTTP: метод, тело, заголовки, версия и redirect; Время ожидания и медленная передача; DNS, IP, локальные соединения и TCP; HTTP-аутентификация и credentials; TLS: доверие, имя, сертификаты и версии; Прокси, SOCKS и отдельный TLS к прокси; Cookie engine и cookie-файлы; Alt-Svc и HSTS; Callback-функции, прогресс и пауза; Получение, отправка и файловые потоки; FTP/FTPS: данные и управляющее соединение; SFTP/SCP: ключ сервера и вход клиента; SMTP: отправитель и получатели; RTSP: сессия медиапотока; TELNET, TFTP и WebSocket; Multi: параллельность, соединения и результаты; Share: какие данные можно разделить; Локальные прикладные метки; Результат, размеры и тайминги CURLINFO; Диагностика: текст, заголовки и данные; CURLE и CURLPX: смысл отказа; Возможности установленной libcurl; Старые имена, неработающие и удалённые настройки.

Адрес и допустимые протоколы

Схема адреса выбирает протокол. Ограничение схем нужно и начальному URL, и переходам; при работе с пользовательскими адресами дополнительно ограничивают фактические адресаты. Ниже сохранены также старые числовые CURLPROTO_* маски, но новый набор схем лучше выражается строками PROTOCOLS_STR.

Для клиента, которому поручено только читать HTTPS API, запретите лишние протоколы. Схема URL выбирает протокол: https:// и file:// запускают принципиально разные действия. Следующий пример только настраивает будущий запрос и никому не подключается.

Адрес и допустимые протоколы
  1. https://api.example.test/catalog — явная схема
  2. PROTOCOLS_STR = https ограничивает начальный адрес
  3. REDIR_PROTOCOLS_STR = https ограничивает переходы
  4. FOLLOWLOCATION = false оставляет redirect решением приложения

Этот вариант. Пример рассчитан на PHP 8.3+ с соответствующим libcurl. В нём нет curl_exec. Даже разрешённый HTTPS может вести на внутренний IP: для адреса от пользователя дополнительно нужна политика адресатов, DNS/IP, proxy и redirect. Список протоколов не является полной защитой SSRF.

Подготовить клиента только для HTTPSСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
if (!curl_setopt_array($handle, [
    CURLOPT_URL => 'https://api.example.test/catalog',
    CURLOPT_PROTOCOLS_STR => 'https',
    CURLOPT_REDIR_PROTOCOLS_STR => 'https',
    CURLOPT_FOLLOWLOCATION => false,
])) throw new RuntimeException('Не удалось настроить политику');
echo "Разрешён HTTPS; автоматические переходы выключены\n";
Ожидаемый результат
Разрешён HTTPS; автоматические переходы выключены
КонстантаНазначение, договор и границы
CURLOPT_PROTOCOLS
Тип самой константы: int

Ограничивает схемы исходной передачи, но старый bitmask не охватывает все современные протоколы; deprecated native с7.85. Новый код PROTOCOLS_STR, redirect ограничить отдельно. CURLPROTO_ALL не означает все будущие протоколы. При open_basedir PHP не разрешает включить FILE.

Значение/результат: int-маска CURLPROTO_*.

По умолчанию: все поддерживаемые, кроме file при open_basedir.

Версии: Доступно с libcurl 7.19.4 and deprecated as of libcurl 7.85.0. Native API: libcurl 7.19.4.

PHP: CURLOPT_PROTOCOLS; libcurl: CURLOPT_PROTOCOLS

CURLOPT_PROTOCOLS_STR
Тип самой константы: int

Allowlist URL schemes без учёта регистра; "https" для внешнего HTTPS API, "http" только для оговорённого loopback урока. ALL разрешает также будущие протоколы новой библиотеки и не годится как ограничение. Неизвестное имя либо отсутствие совпадений вызывает отказ. Официальный PHP перечень включает DICT,FILE,FTP,FTPS,GOPHER,GOPHERS,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,MQTT,POP3,POP3S,RTMP/RTMPE/RTMPS/RTMPT/RTMPTE/RTMPTS,RTSP,SCP,SFTP,SMB,SMBS,SMTP,SMTPS,TELNET,TFTP,WS,WSS; фактическая сборка может не иметь часть исторических и иметь новые, например nativeMQTTS. Проверять curl_version. Нужна также проверка конкретного host/IP/port и redirect.

Значение/результат: string: имена через запятую.

По умолчанию: все поддерживаемые.

Версии: Доступно с PHP 8.3.0 и libcurl 7.85.0. Native API: libcurl 7.85.0.

PHP: CURLOPT_PROTOCOLS_STR; libcurl: CURLOPT_PROTOCOLS_STR

CURLOPT_REDIR_PROTOCOLS
Тип самой константы: int

Ограничивает схемы redirect при FOLLOWLOCATION и не расширяет исходный PROTOCOLS allowlist. Native deprecated с 7.85: bitmask не описывает все схемы; новый код REDIR_PROTOCOLS_STR. До 7.40 default исключал FILE/SCP,7.40–7.65.1 также SMB/SMBS; с 7.65.2 только HTTP/HTTPS/FTP/FTPS. При open_basedir PHP не разрешает FILE.

Значение/результат: int-маска CURLPROTO_*.

По умолчанию: HTTP,HTTPS,FTP,FTPS в текущем libcurl.

Версии: Доступно с libcurl 7.19.4 and deprecated as of libcurl 7.85.0. Native API: libcurl 7.19.4.

PHP: CURLOPT_REDIR_PROTOCOLS; libcurl: CURLOPT_REDIR_PROTOCOLS

CURLOPT_REDIR_PROTOCOLS_STR
Тип самой константы: int

Allowlist схем redirect без учёта регистра, пересекается с PROTOCOLS_STR. ALL разрешает все поддерживаемые и потенциально будущие схемы; для HTTPS клиента явно"https". Перечень схем такой же, как в PROTOCOLS_STR, но конкретную сборку проверяет curl_version. До появления строковой опции правила старого default менялись: до 7.40 все кроме FILE/SCP, затем исключены SMB/SMBS, с 7.65.2 нынешний узкий набор. Ограничение схемы не проверяет доверие host/IP.

Значение/результат: string: schemes через запятую.

По умолчанию: HTTP,HTTPS,FTP,FTPS.

Версии: Доступно с PHP 8.3.0 и libcurl 7.85.0. Native API: libcurl 7.85.0.

PHP: CURLOPT_REDIR_PROTOCOLS_STR; libcurl: CURLOPT_REDIR_PROTOCOLS_STR

CURLOPT_URL
Тип самой константы: int

Адрес scheme://host:port/path. Кодировать надо отдельные компоненты, а не rawurlencode всей URL-строки. Успех setopt ещё не доказывает, что URL будет принят/доступен при exec. При отсутствии схемы возможна эвристика по host либо DEFAULT_PROTOCOL; в приложении задавайте схему явно. IDN зависит от backend/кодировки (на Windows ожидается UTF-8). При пользовательском адресе нужны allowlist схем, политика адресов DNS/IP и каждого redirect: одной проверки текста URL недостаточно против SSRF.

Значение/результат: string.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_URL; libcurl: CURLOPT_URL

CURLPROTO_ALL
Тип самой константы: int

Историческая маска всех перечисленных в старом bitmask API протоколов. В современном libcurl она уже не включает все новые протоколы; с 7.85.0 предпочтительны PROTOCOLS_STR/REDIR_PROTOCOLS_STR. Для недоверенного URL не выбирать «всё».

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_ALL; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_DICT
Тип самой константы: int

Бит DICT — сетевых словарных запросов. Наличие имени константы не доказывает поддержку протокола сборкой.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_DICT; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_FILE
Тип самой константы: int

Бит file:// — доступа к локальным файлам. Не включать в клиент внешних URL: разрешённая схема может открыть локальный ресурс.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_FILE; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_FTP
Тип самой константы: int

Бит обычного FTP. FTP+явный TLS настраивается через USE_SSL; это не то же самое, что разрешить схему ftps://.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_FTP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_FTPS
Тип самой константы: int

Бит FTPS — FTP с TLS, включая схему ftps://. Это не SFTP.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_FTPS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_GOPHER
Тип самой константы: int

Бит Gopher. Его разрешение не требуется обычному HTTP API клиенту.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.2.

PHP: CURLPROTO_GOPHER; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_HTTP
Тип самой константы: int

Бит http://, без TLS. В учебном примере допустим loopback; конфиденциальные внешние запросы требуют HTTPS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_HTTP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_HTTPS
Тип самой константы: int

Бит https:// — HTTP через TLS. Проверка сертификата/имени и разрешение конкретного адреса всё равно обязательны.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_HTTPS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_IMAP
Тип самой константы: int

Бит IMAP — чтения/управления почтовым ящиком; явный STARTTLS настраивается отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_IMAP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_IMAPS
Тип самой константы: int

Бит IMAPS — IMAP через TLS с начала соединения.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_IMAPS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_LDAP
Тип самой константы: int

Бит LDAP — запросов к каталогу; транспортная защита зависит от отдельной настройки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_LDAP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_LDAPS
Тип самой константы: int

Бит LDAPS — LDAP через TLS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_LDAPS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_MQTT
Тип самой константы: int

Бит MQTT — обмена с broker. Не означает поддержку всех MQTT extensions или любого способа аутентификации.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.71.0.

PHP: CURLPROTO_MQTT; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_POP3
Тип самой константы: int

Бит POP3 — получения почты; обычная схема сама TLS не требует.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_POP3; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_POP3S
Тип самой константы: int

Бит POP3 через TLS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_POP3S; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTMP
Тип самой константы: int

Исторический бит RTMP — мультимедийного протокола; применимость зависит от наличия соответствующего backend в сборке.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURLPROTO_RTMP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTMPE
Тип самой константы: int

Исторический бит RTMP с вариантом шифрования E; это не TLS и не синоним HTTPS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURLPROTO_RTMPE; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTMPS
Тип самой константы: int

Исторический бит RTMP через TLS; проверить фактический протокол в runtime.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURLPROTO_RTMPS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTMPT
Тип самой константы: int

Исторический бит RTMP, туннелируемого через HTTP.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURLPROTO_RTMPT; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTMPTE
Тип самой константы: int

Исторический бит туннелируемого через HTTP RTMP с шифрованием E.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURLPROTO_RTMPTE; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTMPTS
Тип самой константы: int

Исторический бит RTMP в защищённом TLS HTTP-туннеле.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURLPROTO_RTMPTS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_RTSP
Тип самой константы: int

Бит RTSP — управления медиасессией. Передача самих медиаданных и RTSP-команды различаются.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_RTSP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_SCP
Тип самой константы: int

Бит SCP — копирования через SSH. Не смешивать с FTP/FTPS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_SCP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_SFTP
Тип самой константы: int

Бит SFTP — файлового протокола SSH; проверка SSH host key и ключа клиента задаются отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_SFTP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_SMB
Тип самой константы: int

Исторический бит SMB доступа к сетевым файлам; поддержка зависит от сборки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0.

PHP: CURLPROTO_SMB; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_SMBS
Тип самой константы: int

Исторический бит SMB через TLS. Это отдельная схема libcurl, не обещание поддержки всех современных Windows SMB режимов.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0.

PHP: CURLPROTO_SMBS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_SMTP
Тип самой константы: int

Бит SMTP — отправки почты серверу; STARTTLS, получатели и авторизация настраиваются отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_SMTP; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_SMTPS
Тип самой константы: int

Бит SMTP через TLS с начала соединения.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURLPROTO_SMTPS; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_TELNET
Тип самой константы: int

Бит Telnet; протокол не предоставляет шифрование сам по себе.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_TELNET; libcurl: CURLOPT_PROTOCOLS

CURLPROTO_TFTP
Тип самой константы: int

Бит TFTP — простой файловой передачи по UDP; это не FTP и не защищённое хранилище.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.4.

PHP: CURLPROTO_TFTP; libcurl: CURLOPT_PROTOCOLS

HTTP: метод, тело, заголовки, версия и redirect

Метод описывает действие, тело содержит данные, заголовки описывают представление и условия. Это связанные настройки: POSTFIELDS выбирает POST, NOBODY — запрос без тела ответа, CUSTOMREQUEST меняет текст метода. Переход на другой URL может также менять метод и политику передачи credentials. Условный запрос по времени/диапазону требует поддержки сервера.

Один и тот же товар можно отправить как форму или JSON, но сервер должен знать, какой формат он получает. Сначала приготовим байты и посмотрим их, затем установим тело. POSTFIELDS со строкой не кодирует данные за вас. POSTFIELDS с массивом выбирает multipart; это третий формат, рассмотренный в карточках файлов.

Из данных товара в JSON body
  1. Массив sku=A42, quantity=2
  2. json_encode → текст JSON
  3. HTTPHEADER → application/json
  4. POSTFIELDS → те же подготовленные байты

Этот вариант. [] создаёт массив; => связывает ключ со значением. http_build_query и json_encode возвращают разные строки из одних данных. Content-Type описывает именно отправленные байты. Здесь POSTFIELDS сам выбирает POST; CUSTOMREQUEST для обычного POST не нужен.

Подготовить форму и JSON без отправкиСамостоятельный пример
<?php
declare(strict_types=1);

$order = ['sku' => 'A42', 'quantity' => 2];
$form = http_build_query($order, '', '&', PHP_QUERY_RFC3986);
$json = json_encode($order, JSON_THROW_ON_ERROR);
echo "Форма: ", $form, "\n";
echo "JSON: ", $json, "\n";
$handle = curl_init('http://127.0.0.1:8772/json');
if ($handle === false) throw new RuntimeException('Нет клиента');
if (!curl_setopt_array($handle, [
    CURLOPT_POSTFIELDS => $json,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
])) throw new RuntimeException('Настройка отклонена');
echo "Подготовлено тело JSON; сеть не использована\n";
Ожидаемый результат
Форма: sku=A42&quantity=2
JSON: {"sku":"A42","quantity":2}
Подготовлено тело JSON; сеть не использована

Практика: замените quantity на 3 и предскажите обе строки. Затем добавьте название с пробелом и сравните кодирование формы и JSON. Не добавляйте вручную Content-Length для строкового POSTFIELDS: PHP/libcurl знают длину в байтах. Переключая один handle между POST, HEAD и GET, явно восстанавливайте согласованное состояние; имя CUSTOMREQUEST само не убирает прежнее тело.

КонстантаНазначение, договор и границы
CURLFOLLOW_ALL
Тип самой константы: int

Режим следования redirect: custom method из CUSTOMREQUEST сохраняется для всех запросов, даже если обычная обработка 301/302/303 изменила бы POST на GET. Учитывайте риск повторного тела/неожиданного метода.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.5.0 и libcurl 8.13.0.

PHP: CURLFOLLOW_ALL; libcurl: CURLOPT_FOLLOWLOCATION

CURLFOLLOW_FIRSTONLY
Тип самой константы: int

Применять CUSTOMREQUEST только к первому запросу, затем выбирать метод по обычным правилам redirect. Это отличается от постоянного ALL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.5.0 и libcurl 8.13.0.

PHP: CURLFOLLOW_FIRSTONLY; libcurl: CURLOPT_FOLLOWLOCATION

CURLFOLLOW_OBEYCODE
Тип самой константы: int

Следовать redirect, подчиняя custom method HTTP-коду: для соответствующих 301/302/303 может применяться GET. POSTREDIR может уточнять сохранение POST. Состояние метода и отправка тела остаются связанными.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.5.0 и libcurl 8.13.0.

PHP: CURLFOLLOW_OBEYCODE; libcurl: CURLOPT_FOLLOWLOCATION

CURLHEADER_SEPARATE
Тип самой константы: int

Разделять HTTPHEADER для origin и PROXYHEADER для proxy. Для CONNECT proxy получает proxy-заголовки, затем origin — свои; обычный non-CONNECT запрос через proxy содержит оба набора. Default с libcurl 7.42.1.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.37.0.

PHP: CURLHEADER_SEPARATE; libcurl: CURLOPT_HEADEROPT

CURLHEADER_UNIFIED
Тип самой константы: int

Один набор HTTPHEADER для origin и proxy, PROXYHEADER игнорируется. Старый default до libcurl 7.42.1; осторожно с секретами origin при передаче прокси.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.37.0.

PHP: CURLHEADER_UNIFIED; libcurl: CURLOPT_HEADEROPT

CURLMIMEOPT_FORMESCAPE
Тип самой константы: int

Для multipart HTTP экранировать имена полей/файлов обратным слешем, как старые реализации, вместо современного percent-encoding кавычек/CR/LF. До libcurl 7.81.0 применялся старый способ. Флаг нужен лишь для согласованного legacy-сервера; не меняет кодировку тела файла.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.3.0 и libcurl 7.81.0

PHP: CURLMIMEOPT_FORMESCAPE; libcurl: CURLOPT_MIME_OPTIONS

CURLOPT_ACCEPT_ENCODING
Тип самой константы: int

Задаёт Accept-Encoding и включает автоматическое декодирование Content-Encoding. Пустая строка просит все доступные сборке алгоритмы; возможны identity, deflate, gzip, br (с7.57), zstd (с7.72). Нужны соответствующие zlib/Brotli/Zstd библиотеки. null выключает и заголовок, и автоматическую распаковку. Один заголовок Accept-Encoding в HTTPHEADER распаковку не включает. Сервер не обязан выбрать запрошенный алгоритм. Content-Length сжатого ответа может отличаться от суммы распакованных callback chunks; ограничивать также распакованный объём.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.21.6. Native API: libcurl 7.21.6.

PHP: CURLOPT_ACCEPT_ENCODING; libcurl: CURLOPT_ACCEPT_ENCODING

CURLOPT_AUTOREFERER
Тип самой константы: int

При автоматическом redirect задаёт Referer равным предыдущему полному URL. Может переносить чувствительные path/query между origin и даже к менее защищённому протоколу. Для секретов в URL не включать автоматически; фактическое значение доступно в CURLINFO_REFERER.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_AUTOREFERER; libcurl: CURLOPT_AUTOREFERER

CURLOPT_CUSTOMREQUEST
Тип самой константы: int

Меняет текст метода/команды, а не внутренний режим libcurl. Для настоящего HEAD используйте NOBODY, POST — POST/POSTFIELDS, GET — HTTPGET. Передавать только разрешённое слово метода, не request line, headers или CRLF: native принимает строку буквально. null возвращает обычный выбор. В HTTP сочетание с FOLLOWLOCATION/POSTREDIR определяет сохранение метода; для FTP заменяет LIST/NLST, IMAP LIST, POP3 LIST/RETR (DELE/NOOP требуют NOBODY), SMTP HELP/VRFY (с MAIL_RCPT возможен EXPN, с NOBODY — NOOP/RSET).

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_CUSTOMREQUEST; libcurl: CURLOPT_CUSTOMREQUEST

CURLOPT_ENCODING
Тип самой константы: int

Историческое имя ACCEPT_ENCODING до7.21.6. Задаёт Accept-Encoding и включает декодирование; "" выбирает поддерживаемые сборкой identity/deflate/gzip/br/zstd. Не кодировка символов. Для нового кода используйте ACCEPT_ENCODING и те же ограничения распакованного объёма.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.10 and deprecated as of libcurl 7.21.6. Native API CURLOPT_ACCEPT_ENCODING: libcurl 7.21.6.

PHP: CURLOPT_ENCODING; libcurl: CURLOPT_ACCEPT_ENCODING

CURLOPT_FAILONERROR
Тип самой константы: int

Преобразовать HTTP>=400 в CURLE_HTTP_RETURNED_ERROR и закрыть соединение. Обычно без флага body HTTP404 возвращается как обычные данные. Механизм не абсолютно надёжен вокруг401/407 и аутентификации; часть headers уже могла поступить. Всегда различать транспортный errno, HTTP status и ошибку прикладного JSON.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_FAILONERROR; libcurl: CURLOPT_FAILONERROR

CURLOPT_FOLLOWLOCATION
Тип самой константы: int

Следовать HTTP30x Location, относительному или абсолютному; ограничить MAXREDIRS и REDIR_PROTOCOLS_STR. POST обычно становится GET на301/302/303, кроме политики POSTREDIR;307/308 сохраняют метод/body. Сlibcurl8.13 режимы ALL/OBEYCODE/FIRSTONLY уточняют CUSTOMREQUEST. По умолчанию чувствительные Authorization/явный Cookie не пересылаются чужому host, но произвольные секретные headers такой защиты не имеют. Старая PHP-фраза «константа недоступна при open_basedir» не описывает8.5: ограничивается file://, а не всё redirect-following. Для строгой проверки каждого адреса переходы обрабатывать вручную.

Значение/результат: int/bool:0 либо CURLFOLLOW_*.

По умолчанию: 0.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_FOLLOWLOCATION; libcurl: CURLOPT_FOLLOWLOCATION

CURLOPT_HEADER
Тип самой константы: int

Включает полученные headers в тот же выход/WRITEFUNCTION, что и body. После этого нельзя надёжно отделить все промежуточные ответы одним простым explode: возможны redirects,100Continue,CONNECT. Обычно лучше отдельный HEADERFUNCTION. Это не HTTPHEADER, который задаёт исходящие headers.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_HEADER; libcurl: CURLOPT_HEADER

CURLOPT_HEADEROPT
Тип самой константы: int

UNIFIED отправляет HTTPHEADER серверу и proxy, PROXYHEADER игнорируется. SEPARATE отделяет CONNECT headers proxy от headers origin; но обычный non-CONNECT запрос через proxy содержит оба списка. Разделение не означает, что proxy не увидит незашифрованный HTTP body.

Значение/результат: int CURLHEADER_UNIFIED|SEPARATE.

По умолчанию: SEPARATE с7.42.1; раньше UNIFIED.

Версии: Доступно с PHP 7.0.7 и libcurl 7.37.0. Native API: libcurl 7.37.0.

PHP: CURLOPT_HEADEROPT; libcurl: CURLOPT_HEADEROPT

CURLOPT_HTTP09_ALLOWED
Тип самой константы: int

Разрешает ответ HTTP/0.9 без headers, только body. Многие случайные TCP-сервисы выглядят так, поэтому включение расширяет допустимое поведение. Не использовать как универсальный способ скрыть ошибку «HTTP/0.9 not allowed».

Значение/результат: bool.

По умолчанию: false с7.66; раньше true.

Версии: Доступно с PHP 7.3.15 and 7.4.3, respectively, и libcurl 7.64.0. Native API: libcurl 7.64.0.

PHP: CURLOPT_HTTP09_ALLOWED; libcurl: CURLOPT_HTTP09_ALLOWED

CURLOPT_HTTP200ALIASES
Тип самой константы: int

Альтернативные полные status lines, распознаваемые как HTTP200, например ICY 200 OK у старого SHOUTcast/Icecast. Версия в alias не разбирается, подразумевается HTTP1.0. Последний список заменяет прежний. Не делает HTTP500 успехом по произвольному business-правилу.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.10.3. Native API: libcurl 7.10.3.

PHP: CURLOPT_HTTP200ALIASES; libcurl: CURLOPT_HTTP200ALIASES

CURLOPT_HTTPGET
Тип самой константы: int

true переключает обратно на GET после POST/HEAD/PUT, обнуляя NOBODY и UPLOAD. false не «отменяет GET» и не выбирает другой метод. CUSTOMREQUEST при необходимости тоже сбрасывается отдельно; reset очищает всё состояние.

Значение/результат: bool.

По умолчанию: false; обычный новый handle и так GET.

Версии: Доступно с libcurl 7.8.1. Native API: libcurl 7.8.1.

PHP: CURLOPT_HTTPGET; libcurl: CURLOPT_HTTPGET

CURLOPT_HTTPHEADER
Тип самой константы: int

Строки "Name: value" без завершающего CRLF; последняя установка заменяет весь список. "Accept:" удаляет внутренний header, "X-Empty;" принудительно отправляет пустое значение. Native принимает управляющие символы буквально: проверять недоверенные values, не допускать CR/LF/NUL. Request line сюда не входит. Connection может быть дополнен libcurl несмотря на override. Host влияет на cookie matching, а в HTTP2/3 становится :authority; Transfer-Encoding:chunked меняет upload framing. Authorization/Proxy-Authorization могут конфликтовать с auth options. Headers следуют за redirects; особая защита чужого host для Authorization действует с7.58, Cookie с7.64, другие секретные headers не защищены. HEADEROPT/PROXYHEADER задают назначения. Native MIME mail может использовать document headers Mime-Version/Content-Type multipart/* без boundary, From/To/Date/Subject; это не автоматическое создание почты из raw upload.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_HTTPHEADER; libcurl: CURLOPT_HTTPHEADER

CURLOPT_HTTP_CONTENT_DECODING
Тип самой константы: int

Разрешение распаковки Content-Encoding. false оставляет закодированный body. Само true ещё не включает декодирование: требуется ненулевой ACCEPT_ENCODING. Не смешивать с Transfer-Encoding chunked и кодировкой Unicode.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с libcurl 7.16.2. Native API: libcurl 7.16.2.

PHP: CURLOPT_HTTP_CONTENT_DECODING; libcurl: CURLOPT_HTTP_CONTENT_DECODING

CURLOPT_HTTP_TRANSFER_DECODING
Тип самой константы: int

Разбирать HTTP transfer framing, прежде всего chunked. false отдаёт raw transfer representation. Это не отключение gzip/br, которые относятся к Content-Encoding.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с libcurl 7.16.2. Native API: libcurl 7.16.2.

PHP: CURLOPT_HTTP_TRANSFER_DECODING; libcurl: CURLOPT_HTTP_TRANSFER_DECODING

CURLOPT_HTTP_VERSION
Тип самой константы: int

Выбор версии/политики fallback описан в группе CURL_HTTP_VERSION_*. Приоритет reuse существующего соединения может привести к иной версии, чем запрошено; проверять CURLINFO_HTTP_VERSION. 2_PRIOR_KNOWLEDGE требует знания сервера и с8.10 предлагает через HTTPS ALPN толькоh2. 3 допускает fallback,3ONLY нет. Константа не обеспечивает поддержку HTTP3 в сборке.

Значение/результат: int CURL_HTTP_VERSION_*.

По умолчанию: NONE с8.13;2TLS с7.62; ранее1_1.

Версии: Доступно с libcurl 7.9.1. Native API: libcurl 7.9.1.

PHP: CURLOPT_HTTP_VERSION; libcurl: CURLOPT_HTTP_VERSION

CURLOPT_KEEP_SENDING_ON_ERROR
Тип самой константы: int

Продолжать отправку body, хотя сервер уже дал HTTP>=300. Обычно libcurl прекращает отправку и закрывает поток/соединение. Специализировано, например, для вручную реализованного NTLM через Authorization; большинству клиентов не нужно. Это не игнорирование итогового статуса.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.51.0. Native API: libcurl 7.51.0.

PHP: CURLOPT_KEEP_SENDING_ON_ERROR; libcurl: CURLOPT_KEEP_SENDING_ON_ERROR

CURLOPT_MAXREDIRS
Тип самой константы: int

Предел автоматических переходов при FOLLOWLOCATION. 0 не следует ни одному, -1 снимает предел и может зациклить клиента. Следующий переход сверх лимита даёт TOO_MANY_REDIRECTS. PHP8.5.11 явно задаёт20 при создании handle, поэтому native default30 не переносится в PHP автоматически.

Значение/результат: int.

По умолчанию: 20 в PHP; native30 с8.3.

Версии: Доступно с libcurl 7.5.0. Native API: libcurl 7.5.

PHP: CURLOPT_MAXREDIRS; libcurl: CURLOPT_MAXREDIRS

CURLOPT_MIME_OPTIONS
Тип самой константы: int

FORMESCAPE возвращает старое backslash-экранирование имён multipart fields/files вместо percent encoding кавычки/CR/LF. До7.81 использовался старый способ; новый default ближе к современным браузерам. Менять только для согласованной совместимости принимающего сервера, не для произвольного URL encoding.

Значение/результат: int-маска CURLMIMEOPT_*.

По умолчанию: 0.

Версии: Доступно с PHP 8.3.0 и libcurl 7.81.0. Native API: libcurl 7.81.0.

PHP: CURLOPT_MIME_OPTIONS; libcurl: CURLOPT_MIME_OPTIONS

CURLOPT_NOBODY
Тип самой константы: int

Для HTTP(S) выбирает HEAD, для других протоколов обычно не запрашивает body. Это протокольный режим, не просто скрытие уже скачанного текста. false переводит HEAD обратно в GET только пока метод остаётся HEAD; яснее явно HTTPGET/POST/UPLOAD. CUSTOMREQUEST другого метода может изменить взаимодействие.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_NOBODY; libcurl: CURLOPT_NOBODY

CURLOPT_POST
Тип самой константы: int

Выбирает обычный HTTP POST, по умолчанию form-urlencoded Content-Type; body задаётся POSTFIELDS либо подходящим read callback. true снимает NOBODY/HTTPGET. false возвращает default метод, но для повторно используемого handle яснее выбрать HTTPGET/NOBODY явно. Тип POSTFIELDS определяет encoding: строка и array имеют разные договоры. Expect:100-continue и chunked зависят от размера/протокола, не гарантированы у каждого малого POST.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_POST; libcurl: CURLOPT_POST

CURLOPT_POSTFIELDS
Тип самой константы: int

PHP-строка передаётся как готовые байты: form-urlencoded создают http_build_query, JSON — json_encode и подходящий Content-Type. PHP копирует строку и задаёт её длину, включая NUL; это отличается от C pointer native POSTFIELDS. Непустой array создаёт multipart/form-data; значения-файлы — CURLFile/CURLStringFile, boundary формирует libcurl. В PHP8.5.11 значение поля-list разворачивается в несколько простых parts с тем же именем, не в произвольное рекурсивное дерево; глубокие arrays/нестроковые objects требуют явной сериализации. Пустой array даёт пустое тело. null в PHP приводится к пустой строке и не выбирает native read-callback режим. Последняя установка заменяет body и выбирает POST. Для JSON не передавать PHP array напрямую.

Значение/результат: string|array.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_POSTFIELDS; libcurl: CURLOPT_POSTFIELDS

CURLOPT_POSTREDIR
Тип самой константы: int

Сохранять POST после выбранных301/302/303 вместо обычного перехода на GET; ALL объединяет три bits. Имеет смысл вместе с FOLLOWLOCATION и настоящим POST/MIMEPOST режимом, а не одним CUSTOMREQUEST="POST". При повторной отправке body думать об идемпотентности и доверии новой цели.

Значение/результат: int-маска CURL_REDIR_POST_*.

По умолчанию: 0.

Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1.

PHP: CURLOPT_POSTREDIR; libcurl: CURLOPT_POSTREDIR

CURLOPT_REFERER
Тип самой константы: int

Исходящий Referer HTTP header; последняя строка заменяет предыдущую. AUTOREFERER может менять его при redirect. Не помещать сюда полный URL с секретными query-параметрами; это заявление клиента, не доказательство источника запроса.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_REFERER; libcurl: CURLOPT_REFERER

CURLOPT_REQUEST_TARGET
Тип самой константы: int

Заменяет request-target, отправляемый серверу, сохраняя отдельно URL для соединения. Строка передаётся буквально, включая нежелательные whitespace/control characters; принимать только заранее определённую форму. Например"*" у OPTIONS, а не полный произвольный HTTP-запрос. null возвращает target из URL.

Значение/результат: string|null.

По умолчанию: path из URL.

Версии: Доступно с PHP 7.3.0 и libcurl 7.55.0. Native API: libcurl 7.55.0.

PHP: CURLOPT_REQUEST_TARGET; libcurl: CURLOPT_REQUEST_TARGET

CURLOPT_RETURNTRANSFER
Тип самой константы: int

PHP write handler возвращает собранный ответ строкой из curl_exec вместо немедленного вывода. Ошибка — строго false; пустая строка и"0" могут быть успешными. Весь ответ хранится в памяти: для большого файла использовать stream/WRITEFUNCTION и лимит. Последующая смена write handler может изменить этот режим; установить согласованную политику вывода до exec.

Значение/результат: bool.

По умолчанию: false.

PHP: CURLOPT_RETURNTRANSFER

CURLOPT_STREAM_WEIGHT
Тип самой константы: int

Относительный вес HTTP/2 потока среди соседних потоков. Например веса 16 и 32 выражают предпочтение 1:2, если сервер применяет эту схему. Это не гарантированные доли пропускной способности и не приоритет процессов ОС. Имеет смысл для конкурентных передач через одно HTTP/2 соединение; современная приоритизация сервера может отличаться.

Значение/результат: int: 1…256.

По умолчанию: 16.

Версии: Доступно с PHP 7.0.7 и libcurl 7.46.0. Native API: libcurl 7.46.0.

PHP: CURLOPT_STREAM_WEIGHT; libcurl: CURLOPT_STREAM_WEIGHT

CURLOPT_TIMECONDITION
Тип самой константы: int

Условие по времени изменения ресурса, которое задаёт TIMEVALUE/TIMEVALUE_LARGE: IFMODSINCE либо IFUNMODSINCE, NONE отключает. Сервер может не предоставить время/не поддержать условие; смотрите HTTP-статус и CURLINFO_CONDITION_UNMET. HTTP 304 возникает из протокольного условия, а не из включения CURLOPT_HEADER. Старый default до libcurl 7.46 отличался.

Значение/результат: int: CURL_TIMECOND_*.

По умолчанию: CURL_TIMECOND_NONE в современном libcurl.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_TIMECONDITION; libcurl: CURLOPT_TIMECONDITION

CURLOPT_TIMEVALUE
Тип самой константы: int

Время сравнения для TIMECONDITION. Само по себе не включает условную передачу. Native вариант использует C long: на платформе с 32-битным long ограничен эпохой 2038; для широкого диапазона нужен TIMEVALUE_LARGE и достаточно широкий PHP int.

Значение/результат: int: Unix timestamp, секунды.

По умолчанию: 0.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_TIMEVALUE; libcurl: CURLOPT_TIMEVALUE

CURLOPT_TIMEVALUE_LARGE
Тип самой константы: int

Вариант TIMEVALUE через native curl_off_t, полезен на Windows с 32-битным C long. PHP int всё равно должен представлять выбранную дату. Это секунды Unix, не миллисекунды и не форматированная дата; TIMECONDITION задаётся отдельно.

Значение/результат: int: Unix timestamp, секунды.

По умолчанию: 0.

Версии: Доступно с PHP 7.3.0 и libcurl 7.59.0. Native API: libcurl 7.59.0.

PHP: CURLOPT_TIMEVALUE_LARGE; libcurl: CURLOPT_TIMEVALUE_LARGE

CURLOPT_TRANSFER_ENCODING
Тип самой константы: int

Запрашивать сжатый Transfer-Encoding (TE) и декодировать его. Это передаточное кодирование между узлами, а не Content-Encoding представления ресурса. Серверы редко поддерживают такой запрос; для обычного gzip/br ответа используется ACCEPT_ENCODING.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.21.6. Native API: libcurl 7.21.6.

PHP: CURLOPT_TRANSFER_ENCODING; libcurl: CURLOPT_TRANSFER_ENCODING

CURLOPT_UPKEEP_INTERVAL_MS
Тип самой константы: int

Интервал, после которого явный вызов curl_upkeep выполняет обслуживание соединения, сейчас прежде всего HTTP/2 PING. Самостоятельный фоновый таймер не создаётся: приложение должно вызывать curl_upkeep. Native имя CURL_UPKEEP_INTERVAL_DEFAULT описывает default, но не экспортируется как PHP-константа.

Значение/результат: int: миллисекунды.

По умолчанию: 60000.

Версии: Доступно с PHP 8.2.0 и libcurl 7.62.0. Native API: libcurl 7.62.0.

PHP: CURLOPT_UPKEEP_INTERVAL_MS; libcurl: CURLOPT_UPKEEP_INTERVAL_MS

CURLOPT_USERAGENT
Тип самой константы: int

Значение HTTP User-Agent, например имя/версия своего клиента. Это самодекларация, не подтверждение личности и не механизм обхода доступа. Не включайте в строку секреты, CR/LF или непроверенный пользовательский текст.

Значение/результат: string|null.

По умолчанию: не отправлять специальный User-Agent.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_USERAGENT; libcurl: CURLOPT_USERAGENT

CURL_HTTP_VERSION_1_0
Тип самой константы: int

Запрашивать HTTP/1.0. Не включает TLS и не является настройкой версии PHP.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_HTTP_VERSION_1_0; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_1_1
Тип самой константы: int

Запрашивать HTTP/1.1; HTTP/2 multiplexing при таком выборе не является целью запроса.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_HTTP_VERSION_1_1; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_2
Тип самой константы: int

Современное имя значения 2_0: попытаться HTTP/2 с допустимым откатом к HTTP/1.1 при невозможности согласования.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.43.0

PHP: CURL_HTTP_VERSION_2; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_2TLS
Тип самой константы: int

Пробовать HTTP/2 только для HTTPS, с откатом к 1.1. Для незашифрованного HTTP используется 1.1.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.47.0

PHP: CURL_HTTP_VERSION_2TLS; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_2_0
Тип самой константы: int

Попытаться HTTP/2; допускается HTTP/1.1 fallback. Для обязательного минимального TLS задайте SSLVERSION отдельно: выбор HTTP/2 сам не задаёт все TLS-политики.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.33.0

PHP: CURL_HTTP_VERSION_2_0; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE
Тип самой константы: int

Для HTTP начать сразу HTTP/2 без Upgrade, если заранее известно о поддержке сервера. Для HTTPS протокол согласуется TLS; начиная с libcurl 8.10.0 в ALPN здесь предлагается только HTTP/2.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.49.0

PHP: CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_3
Тип самой константы: int

Пробовать HTTP/3, допуская fallback к прежним HTTP-версиям. Наличие константы не доказывает поддержку QUIC/HTTP3 сборкой.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.4.0 и libcurl 7.66.0.

PHP: CURL_HTTP_VERSION_3; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_3ONLY
Тип самой константы: int

Требовать HTTP/3 без отката к HTTP/2/1.1; отсутствие поддержки должно привести к отказу. В проверенной сборке главы HTTP3 feature выключен.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.4.0 и libcurl 7.88.0.

PHP: CURL_HTTP_VERSION_3ONLY; libcurl: CURLOPT_HTTP_VERSION

CURL_HTTP_VERSION_NONE
Тип самой константы: int

Дать libcurl выбрать HTTP-версию. Default начиная с libcurl 8.13.0; раньше с 7.62.0 default был 2TLS, ещё раньше 1_1.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_HTTP_VERSION_NONE; libcurl: CURLOPT_HTTP_VERSION

CURL_REDIR_POST_301
Тип самой константы: int

Бит: после HTTP 301 сохранить POST вместо стандартного перехода к GET.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.18.2

PHP: CURL_REDIR_POST_301; libcurl: CURLOPT_POSTREDIR

CURL_REDIR_POST_302
Тип самой константы: int

Бит: после HTTP 302 сохранить POST вместо перехода к GET.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.18.2

PHP: CURL_REDIR_POST_302; libcurl: CURLOPT_POSTREDIR

CURL_REDIR_POST_303
Тип самой константы: int

Бит: после HTTP 303 сохранить POST вместо перехода к GET; это сознательное отклонение от обычного сценария «после POST открыть GET».

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.25.1

PHP: CURL_REDIR_POST_303; libcurl: CURLOPT_POSTREDIR

CURL_REDIR_POST_ALL
Тип самой константы: int

Объединение битов сохранения POST для 301, 302, 303. Это не разрешение redirect вообще: FOLLOWLOCATION включается отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.18.2

PHP: CURL_REDIR_POST_ALL; libcurl: CURLOPT_POSTREDIR

CURL_TIMECOND_IFMODSINCE
Тип самой константы: int

Передавать ресурс, если он изменён после TIMEVALUE. Если сервер не знает время изменения, условие может не действовать; проверять CONDITION_UNMET и протокольный статус.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_TIMECOND_IFMODSINCE; libcurl: CURLOPT_TIMECONDITION

CURL_TIMECOND_IFUNMODSINCE
Тип самой константы: int

Передавать ресурс при отсутствии изменений после TIMEVALUE. Это временное условие, а не защита от конкурентной записи по версии объекта.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_TIMECOND_IFUNMODSINCE; libcurl: CURLOPT_TIMECONDITION

CURL_TIMECOND_LASTMOD
Тип самой константы: int

Исторический элемент перечисления. Актуальная документация TIMECONDITION определяет рабочие условия IFMODSINCE/IFUNMODSINCE и NONE; LASTMOD не является способом прочитать дату. Для чтения используйте FILETIME + CURLINFO_FILETIME.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_TIMECOND_LASTMOD; libcurl: CURLOPT_TIMECONDITION

CURL_TIMECOND_NONE
Тип самой константы: int

0, default: временное условие выключено.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_TIMECOND_NONE; libcurl: CURLOPT_TIMECONDITION

Время ожидания и медленная передача

Покупатель не должен ждать интеграцию бесконечно. Общий TIMEOUT включает установление соединения; CONNECTTIMEOUT ограничивает только эту фазу. LOW_SPEED_LIMIT и LOW_SPEED_TIME отвечают на другой вопрос: достаточно ли долго скорость оставалась ниже заданной. Выбирайте бюджет из задачи приложения, а не из произвольного большого числа.

Бюджет запроса 1500 ms
  1. Соединение занимает часть общих 1500 ms
  2. CONNECTTIMEOUT_MS=500 ограничивает эту часть
  3. TIMEOUT_MS=1500 не прибавляет ещё 1500 после соединения
  4. При отказе приложение решает, безопасен ли повтор
КонстантаНазначение, договор и границы
CURLOPT_CONNECTTIMEOUT
Тип самой константы: int

Лимит фазы соединения: DNS и необходимые handshake/согласования до установленного соединения. 0 возвращает встроенный300s, а не бесконечность (в PHP constants сохранилась неточная фраза). Последняя установка секундной или миллисекундной версии побеждает. Общий TIMEOUT включает эту фазу:3s connect и5s total не дают8s. Системный синхронный resolver может использовать SIGALRM; учитывать NOSIGNAL.

Значение/результат: int, секунды.

По умолчанию: 300.

Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7.

PHP: CURLOPT_CONNECTTIMEOUT; libcurl: CURLOPT_CONNECTTIMEOUT

CURLOPT_CONNECTTIMEOUT_MS
Тип самой константы: int

То же соединение/DNS/handshake, в миллисекундах; 0 возвращает default300s. Последняя из CONNECTTIMEOUT и CONNECTTIMEOUT_MS заменяет другую. С синхронным системным resolver DNS может иметь секундную точность и минимальный1s. Общий TIMEOUT_MS охватывает и соединение; после его установления connect-limit не ограничивает дальнейшее чтение.

Значение/результат: int, миллисекунды.

По умолчанию: 300000.

Версии: Доступно с libcurl 7.16.2. Native API: libcurl 7.16.2.

PHP: CURLOPT_CONNECTTIMEOUT_MS; libcurl: CURLOPT_CONNECTTIMEOUT_MS

CURLOPT_EXPECT_100_TIMEOUT_MS
Тип самой константы: int

Ожидание промежуточного HTTP100 Continue/417 или подобного ответа после Expect:100-continue. По истечении libcurl всё равно отправляет body; это не отказ и не общий лимит запроса.

Значение/результат: int, миллисекунды.

По умолчанию: 1000.

Версии: Доступно с PHP 7.0.7 и libcurl 7.36.0. Native API: libcurl 7.36.0.

PHP: CURLOPT_EXPECT_100_TIMEOUT_MS; libcurl: CURLOPT_EXPECT_100_TIMEOUT_MS

CURLOPT_FTP_RESPONSE_TIMEOUT
Тип самой константы: int

Историческое имя SERVER_RESPONSE_TIMEOUT: лимит ожидания ответа на протокольную команду. Native рекомендует задавать меньше общего TIMEOUT; старую фразу PHP «overrides TIMEOUT» не следует понимать как отмену общего ограничения. Старое native-имя deprecated с7.85; новый PHP-символ доступен с8.4.

Значение/результат: int, секунды.

По умолчанию: 60 в текущем native.

Версии: Доступно с libcurl 7.10.8 and deprecated as of libcurl 7.85.0. Native API CURLOPT_SERVER_RESPONSE_TIMEOUT: libcurl 7.20.0.

PHP: CURLOPT_FTP_RESPONSE_TIMEOUT; libcurl: CURLOPT_SERVER_RESPONSE_TIMEOUT

CURLOPT_LOW_SPEED_LIMIT
Тип самой константы: int

Средняя скорость должна быть ниже этого порога на протяжении LOW_SPEED_TIME секунд, чтобы libcurl отменил слишком медленную передачу. Нужны оба значения; это не верхний speed cap и не минимальная гарантированная скорость сети.

Значение/результат: int, байты/секунду.

По умолчанию: 0: выключено.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_LOW_SPEED_LIMIT; libcurl: CURLOPT_LOW_SPEED_LIMIT

CURLOPT_LOW_SPEED_TIME
Тип самой константы: int

Продолжительность недопустимо низкой средней скорости, установленной LOW_SPEED_LIMIT. Применяется в процессе передачи, в отличие от CONNECTTIMEOUT. Сочетается с общим TIMEOUT, не заменяет его.

Значение/результат: int, секунды.

По умолчанию: 0: выключено.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_LOW_SPEED_TIME; libcurl: CURLOPT_LOW_SPEED_TIME

CURLOPT_SERVER_RESPONSE_TIMEOUT
Тип самой константы: int

Время ожидания командного ответа FTP/SFTP/IMAP/SCP/SMTP/POP3, не общий HTTP response timeout. Общий TIMEOUT может завершить передачу раньше. Новое имя доступно с PHP 8.4; прежнее FTP_RESPONSE_TIMEOUT deprecated в native с 7.85. Не путать с CONNECTTIMEOUT.

Значение/результат: int: секунды.

По умолчанию: 60.

Версии: Доступно с PHP 8.4.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_SERVER_RESPONSE_TIMEOUT; libcurl: CURLOPT_SERVER_RESPONSE_TIMEOUT

CURLOPT_TIMEOUT
Тип самой константы: int

Верхний лимит всего обмена, включая очередь multi, DNS и фазу соединения. CONNECTTIMEOUT действует внутри него, а не прибавляется. 0 снимает именно общий лимит, не ограничения других фаз. TIMEOUT_MS задаёт тот же лимит в миллисекундах; последний вызов выигрывает. Системный синхронный resolver/сигналы могут ограничить точность.

Значение/результат: int: секунды.

По умолчанию: 0: общего лимита нет.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_TIMEOUT; libcurl: CURLOPT_TIMEOUT

CURLOPT_TIMEOUT_MS
Тип самой константы: int

То же общее время, что TIMEOUT, в миллисекундах. При системном resolver DNS может иметь секундное разрешение и минимальный таймаут порядка секунды. Это не обещание прерывания ровно в указанную миллисекунду; CONNECTTIMEOUT_MS отдельно ограничивает фазу соединения.

Значение/результат: int: миллисекунды.

По умолчанию: 0: общего лимита нет.

Версии: Доступно с libcurl 7.16.2. Native API: libcurl 7.16.2.

PHP: CURLOPT_TIMEOUT_MS; libcurl: CURLOPT_TIMEOUT_MS

DNS, IP, локальные соединения и TCP

До HTTP-ответа клиент выбирает адрес, открывает соединение и иногда повторно использует уже открытое. DNS cache, IPRESOLVE, RESOLVE и CONNECT_TO решают разные задачи. Замена фактического IP не обязана менять Host/TLS имя. TCP keepalive проверяет простаивающее соединение средствами ОС, а не отправляет повторный HTTP-запрос.

К кому и как соединиться
  1. URL задаёт имя сервиса
  2. DNS/RESOLVE выбирает IP
  3. Proxy/socket/интерфейс определяет маршрут
  4. Пул может предоставить уже открытое соединение
  5. Только затем выполняется прикладной обмен
КонстантаНазначение, договор и границы
CURLOPT_ABSTRACT_UNIX_SOCKET
Тип самой константы: int

Заменяет TCP на abstract Unix socket. Имя передать без ведущего NUL: libcurl добавляет его сам. Семантика как у UNIX_SOCKET_PATH; они используют одно внутреннее поле, последнее значение заменяет предыдущее. На платформе без abstract sockets операция завершается ошибкой, а не становится обычным Windows-путём.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.53.0. Native API: libcurl 7.53.0.

PHP: CURLOPT_ABSTRACT_UNIX_SOCKET; libcurl: CURLOPT_ABSTRACT_UNIX_SOCKET

CURLOPT_ADDRESS_SCOPE
Тип самой константы: int

Scope ID для соединения с IPv6-адресом, например link-local адресом на определённом интерфейсе. Это не TCP-порт и не маска подсети.

Значение/результат: int.

По умолчанию: 0.

Версии: Доступно с libcurl 7.19.0. Native API: libcurl 7.19.0.

PHP: CURLOPT_ADDRESS_SCOPE; libcurl: CURLOPT_ADDRESS_SCOPE

CURLOPT_CONNECT_ONLY
Тип самой константы: int

1 выполняет proxy-auth и подготовку соединения без обычной передачи. 2 в актуальном native предназначен для WebSocket: выполнить upgrade и прочитать headers, затем передать управление приложению; для других протоколов поведение2 не определено. Connect-only соединения не берутся из пула и не переиспользуются. PHP ext-curl не предоставляет все native curl_easy_send/recv/ws API, поэтому не выдаём этот флаг за готовый PHP WebSocket клиент.

Значение/результат: int 0|1|2.

По умолчанию: 0.

Версии: Доступно с libcurl 7.15.2. Native API: libcurl 7.15.2.

PHP: CURLOPT_CONNECT_ONLY; libcurl: CURLOPT_CONNECT_ONLY

CURLOPT_CONNECT_TO
Тип самой константы: int

Каждая строка HOST:PORT:CONNECT-TO-HOST:CONNECT-TO-PORT направляет сетевое соединение к другому узлу. Первый совпавший элемент побеждает; пустые HOST/PORT совпадают с любыми, пустые target-поля сохраняют исходные. IPv6 пишется в [скобках]. URL host, SNI, имя сертификата и прикладной Host не меняются. В отличие от RESOLVE не заполняет общий DNS cache. Через HTTP proxy отличающийся target требует tunnel, который libcurl включает автоматически. Полезно для собственного тестового узла, не для обхода проверки доверия.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с PHP 7.0.7 и libcurl 7.49.0. Native API: libcurl 7.49.0.

PHP: CURLOPT_CONNECT_TO; libcurl: CURLOPT_CONNECT_TO

CURLOPT_DEFAULT_PROTOCOL
Тип самой константы: int

Схема для URL без scheme. Неизвестная/неподдерживаемая схема обнаруживается при исполнении, а не обязательно setopt. Не меняет default proxy protocol http. Лучше передавать явный проверенный URL, чем полагаться на угадывание. Список доступного узнают в curl_version; настройка не является allowlist.

Значение/результат: string|null.

По умолчанию: null: libcurl угадывает по host.

Версии: Доступно с PHP 7.0.7 и libcurl 7.45.0. Native API: libcurl 7.45.0.

PHP: CURLOPT_DEFAULT_PROTOCOL; libcurl: CURLOPT_DEFAULT_PROTOCOL

CURLOPT_DNS_CACHE_TIMEOUT
Тип самой константы: int

Время кеширования результатов DNS, не фактический DNS TTL записи. 0 выключает, -1 хранит без срока; слишком большой кеш расходует память. С8.1 libcurl всё равно сокращает кеш свыше30000 записей. С8.16 кеширует отрицательный ответ на половину срока; с8.22 только «имя не существует», не временный/локальный сбой resolver. PHP при создании handle явно устанавливает120L. Старые resolver могут не перечитать DHCP DNS-настройки, что выглядит как проблема кеша.

Значение/результат: int, секунды.

По умолчанию: 120 в PHP8.5.11; native default60.

Версии: Доступно с libcurl 7.9.3. Native API: libcurl 7.9.3.

PHP: CURLOPT_DNS_CACHE_TIMEOUT; libcurl: CURLOPT_DNS_CACHE_TIMEOUT

CURLOPT_DNS_INTERFACE
Тип самой константы: int

Имя сетевого интерфейса для DNS resolver, не IP-адрес. Требует подходящей c-ares сборки; обычный системный resolver не обязан поддерживать. null возвращает default привязку.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.0.7 и libcurl 7.33.0 Native API: libcurl 7.33.0.

PHP: CURLOPT_DNS_INTERFACE; libcurl: CURLOPT_DNS_INTERFACE

CURLOPT_DNS_LOCAL_IP4
Тип самой константы: int

Один числовой локальный IPv4 адрес, к которому привязывается DNS resolver; не адрес DNS сервера. Требует c-ares поддержки. null снимает явную привязку.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.0.7 и libcurl 7.33.0. Native API: libcurl 7.33.0.

PHP: CURLOPT_DNS_LOCAL_IP4; libcurl: CURLOPT_DNS_LOCAL_IP4

CURLOPT_DNS_LOCAL_IP6
Тип самой константы: int

Один локальный IPv6 адрес для исходящих запросов DNS resolver; требует c-ares поддержки. Для DNS-серверов используется DNS_SERVERS, для HTTP-соединения — INTERFACE.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.0.7 и libcurl 7.33.0. Native API: libcurl 7.33.0.

PHP: CURLOPT_DNS_LOCAL_IP6; libcurl: CURLOPT_DNS_LOCAL_IP6

CURLOPT_DNS_SERVERS
Тип самой константы: int

Список host[:port],host[:port] задаёт собственные DNS-серверы для поддерживающего c-ares resolver. Не гарантирует работу в любой Windows-сборке; setopt может вернуть false. null возвращает системную настройку.

Значение/результат: string|null.

По умолчанию: null: системные DNS.

Версии: Доступно с libcurl 7.24.0. Native API: libcurl 7.24.0.

PHP: CURLOPT_DNS_SERVERS; libcurl: CURLOPT_DNS_SERVERS

CURLOPT_DNS_SHUFFLE_ADDRESSES
Тип самой константы: int

Перемешивает несколько полученных IP-адресов. Попадание в DNS cache повторно не перемешивается. Порядок перестаёт следовать детерминированным правилам resolver/RFC3484; IPv4 может оказаться раньше IPv6 и наоборот, что влияет на производительность.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.60.0. Native API: libcurl 7.60.0.

PHP: CURLOPT_DNS_SHUFFLE_ADDRESSES; libcurl: CURLOPT_DNS_SHUFFLE_ADDRESSES

CURLOPT_DOH_SSL_VERIFYHOST
Тип самой константы: int

Проверять имя в сертификате DNS-over-HTTPS сервера отдельно от целевого HTTPS сервера. 2 — проверять,0 — выключить; native также принимает1 как2, но документируемый ясный режим2. Не отключать для обхода ошибки сертификата.

Значение/результат: int 2|0.

По умолчанию: 2.

Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0. Native API: libcurl 7.76.0.

PHP: CURLOPT_DOH_SSL_VERIFYHOST; libcurl: CURLOPT_DOH_SSL_VERIFYHOST

CURLOPT_DOH_SSL_VERIFYPEER
Тип самой константы: int

Проверка доверенной цепочки DoH-сервера, отдельно от DOH_SSL_VERIFYHOST. Использует CAINFO/CAPATH; выключение позволяет подмену DNS даже при шифрованном соединении. Основной SSL_VERIFYPEER эту настройку автоматически не заменяет.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0. Native API: libcurl 7.76.0.

PHP: CURLOPT_DOH_SSL_VERIFYPEER; libcurl: CURLOPT_DOH_SSL_VERIFYPEER

CURLOPT_DOH_SSL_VERIFYSTATUS
Тип самой константы: int

Требовать OCSP stapling для сертификата DoH-сервера. Если сервер не поддерживает Certificate Status Request, проверка не проходит. Это отдельная политика от обычного доверия CA.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0. Native API: libcurl 7.76.0.

PHP: CURLOPT_DOH_SSL_VERIFYSTATUS; libcurl: CURLOPT_DOH_SSL_VERIFYSTATUS

CURLOPT_DOH_URL
Тип самой константы: int

Адрес DNS-over-HTTPS endpoint; libcurl отправляет POST. Синтаксис/доступность проверяются при передаче, setopt=true недостаточно. Имя самого DoH-сервера сначала разрешается обычным resolver, либо задаётся через RESOLVE. DoH не наследует proxy options родительского transfer; имя/цепочка TLS управляются отдельными DOH_SSL_*. Некоторые разрешения (INTERFACE, FTPPORT, SOCKS4/5) остаются обычными DNS; это не обещание шифровать абсолютно все DNS процесса.

Значение/результат: string|null: HTTPS URL.

По умолчанию: null.

Версии: Доступно с PHP 8.1.0 и libcurl 7.62.0. Native API: libcurl 7.62.0.

PHP: CURLOPT_DOH_URL; libcurl: CURLOPT_DOH_URL

CURLOPT_FORBID_REUSE
Тип самой константы: int

После передачи закрыть соединение и не помещать его в пул. Это отличается от FRESH_CONNECT, который требует новое соединение до передачи. Без причины ухудшает повторные запросы из-за DNS/TCP/TLS затрат.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7.

PHP: CURLOPT_FORBID_REUSE; libcurl: CURLOPT_FORBID_REUSE

CURLOPT_FRESH_CONNECT
Тип самой константы: int

Начать следующую передачу на новом соединении, даже если есть пригодное в пуле. Не обязывает закрыть новое соединение после ответа; для этого есть FORBID_REUSE.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7.

PHP: CURLOPT_FRESH_CONNECT; libcurl: CURLOPT_FRESH_CONNECT

CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS
Тип самой константы: int

Интервал начала следующей попытки к адресу, пока прежняя не дала результата; обычно IPv6 получает первый шанс, затем чередуются IPv4/IPv6. Успешная попытка оставляет одно соединение, другие закрываются; общий CONNECTTIMEOUT_MS отсчитывается с первой. В текущем native одновременно до6 попыток, старейшая заменяется при новых адресах. Аналогичный интервал используется для HTTP/3 QUIC и fallback TCP. CURL_HET_DEFAULT — native macro, не доступная PHP-константа.

Значение/результат: int, миллисекунды.

По умолчанию: 200.

Версии: Доступно с PHP 7.3.0 и libcurl 7.59.0 Native API: libcurl 7.59.0.

PHP: CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS; libcurl: CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS

CURLOPT_HAPROXYPROTOCOL
Тип самой константы: int

Посылает HAProxy PROXY protocol v1 header в начале нового соединения. Требует сервиса, который специально ожидает этот префикс; обычный HTTP сервер может его отвергнуть. При reuse старого соединения заголовок заново не отправляется.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.60.0. Native API: libcurl 7.60.0.

PHP: CURLOPT_HAPROXYPROTOCOL; libcurl: CURLOPT_HAPROXYPROTOCOL

CURLOPT_INTERFACE
Тип самой константы: int

Исходящий интерфейс, IP или hostname. Префиксы if!name,host!name и ifhost!interface!host (последний с8.9) уточняют смысл; отсутствующий interface даёт INTERFACE_FAILED. Windows не поддерживает здесь имена сетевых интерфейсов, используйте подходящий локальный IP. Hostname вызывает блокирующий DNS вне DoH. Это локальный адрес источника, не сервер назначения.

Значение/результат: string|null.

По умолчанию: null: выбор ОС.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.3.

PHP: CURLOPT_INTERFACE; libcurl: CURLOPT_INTERFACE

CURLOPT_IPRESOLVE
Тип самой константы: int

Выбор семейства IP при DNS/подборе соединения из пула: V4,V6 либо любое. Если URL уже содержит числовой IP, настройка не запрещает его семейство. Это не фильтр допустимых сетей и не защита от внутренних адресов.

Значение/результат: int CURL_IPRESOLVE_*.

По умолчанию: WHATEVER.

Версии: Доступно с libcurl 7.10.8. Native API: libcurl 7.10.8.

PHP: CURLOPT_IPRESOLVE; libcurl: CURLOPT_IPRESOLVE

CURLOPT_LOCALPORT
Тип самой константы: int

Локальный port исходящего socket; не port удалённого сервера. Полезен вместе с LOCALPORTRANGE и INTERFACE в контролируемой сети. Один закреплённый занятый port может сорвать запрос.

Значение/результат: int,0 либо1..65535.

По умолчанию: 0: выбирает ОС.

Версии: Доступно с libcurl 7.15.2. Native API: libcurl 7.15.2.

PHP: CURLOPT_LOCALPORT; libcurl: CURLOPT_LOCALPORT

CURLOPT_LOCALPORTRANGE
Тип самой константы: int

Сколько последовательных локальных ports пробовать от LOCALPORT, увеличивая на1. Значение1 или меньше означает одну попытку. Это количество попыток, не последний port диапазона.

Значение/результат: int: число попыток.

По умолчанию: 1.

Версии: Доступно с libcurl 7.15.2. Native API: libcurl 7.15.2.

PHP: CURLOPT_LOCALPORTRANGE; libcurl: CURLOPT_LOCALPORTRANGE

CURLOPT_MAXAGE_CONN
Тип самой константы: int

Максимальный простой существующего соединения для reuse. Слишком старое закрывается вместо попытки использовать его. Это возраст бездействия, не полное время жизни; для полного возраста MAXLIFETIME_CONN.

Значение/результат: int, секунды.

По умолчанию: 118.

Версии: Доступно с PHP 8.2.0 и libcurl 7.65.0. Native API: libcurl 7.65.0.

PHP: CURLOPT_MAXAGE_CONN; libcurl: CURLOPT_MAXAGE_CONN

CURLOPT_MAXCONNECTS
Тип самой константы: int

Максимум сохранённых соединений easy cache после использования; при заполнении закрывается старейшее. Не ограничивает суммарное число активных запросов. Внутри multi эта easy-настройка игнорируется: нужен CURLMOPT_MAXCONNECTS. Уменьшение после передач может преждевременно закрыть кеш.

Значение/результат: int.

По умолчанию: 5.

Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7.

PHP: CURLOPT_MAXCONNECTS; libcurl: CURLOPT_MAXCONNECTS

CURLOPT_MAXLIFETIME_CONN
Тип самой константы: int

Максимальный полный возраст соединения с создания, после которого его не переиспользуют и закрывают после текущих передач. 0 выключает. Отличается от MAXAGE_CONN — простоя. Может помочь распределению по новым backend addresses; не прерывает запрос в середине. Старый default0 в PHP constants относится к прежним libcurl.

Значение/результат: int, секунды.

По умолчанию: 86400 сlibcurl8.17; раньше0.

Версии: Доступно с PHP 8.2.0 и libcurl 7.80.0. Native API: libcurl 7.80.0.

PHP: CURLOPT_MAXLIFETIME_CONN; libcurl: CURLOPT_MAXLIFETIME_CONN

CURLOPT_NOSIGNAL
Тип самой константы: int

Не использовать сигнальные механизмы libcurl; нужно для многопоточного Unix. С обычным синхронным resolver может сделать DNS неограниченным timeout во время разрешения: для точных сроков нужен c-ares/threaded resolver. Не гарантирует отсутствие любого SIGPIPE ОС и не подавляет внешние сигналы процесса.

Значение/результат: bool.

По умолчанию: true в ZTS PHP; nativefalse/NTS default.

Версии: Доступно с libcurl 7.10. Native API: libcurl 7.10.

PHP: CURLOPT_NOSIGNAL; libcurl: CURLOPT_NOSIGNAL

CURLOPT_PATH_AS_IS
Тип самой константы: int

Не удалять /./ и /../ в path первого URL согласно обычной RFC3986 нормализации. При последующих redirect режим может не сохраниться. Специализирован для проверки/совместимости сервера; не фильтр traversal и не разрешение принимать пользовательский путь без проверки.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.42.0. Native API: libcurl 7.42.0.

PHP: CURLOPT_PATH_AS_IS; libcurl: CURLOPT_PATH_AS_IS

CURLOPT_PIPEWAIT
Тип самой константы: int

При включённом multi multiplexing ждать выяснения возможностей создающегося соединения, чтобы переиспользовать его, вместо немедленного открытия нового. Уменьшает число соединений ценой ожидания. Сам не включает CURLMOPT_PIPELINING и не создаёт HTTP2/3 поддержку.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.43.0. Native API: libcurl 7.43.0.

PHP: CURLOPT_PIPEWAIT; libcurl: CURLOPT_PIPEWAIT

CURLOPT_PORT
Тип самой константы: int

Переопределяет remote port из URL; native не рекомендует из-за неочевидной области действия. Яснее явно указать port в проверенном URL. 0 выключает override, поэтому запросить port0 через эту опцию нельзя; вне диапазона ошибка.

Значение/результат: int,0..65535.

По умолчанию: 0: использовать URL.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_PORT; libcurl: CURLOPT_PORT

CURLOPT_QUICK_EXIT
Тип самой константы: int

При timeout пропустить долгую уборку, если всё приложение немедленно завершается: например не ждать DNS resolver thread. Возможна краткоживущая утечка ресурсов. Не общий ускоритель запросов и не подходит долгоживущему PHP worker, который продолжает работу.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 8.3.0 и libcurl 7.87.0. Native API: libcurl 7.87.0.

PHP: CURLOPT_QUICK_EXIT; libcurl: CURLOPT_QUICK_EXIT

CURLOPT_RESOLVE
Тип самой константы: int

Правила [+]HOST:PORT:ADDRESS[,ADDRESS] заполняют DNS cache; IPv6 в[скобках], *host wildcard проверяется после точных правил. Без+ запись не истекает, с+ действует обычный DNS timeout; -HOST:PORT удаляет точное правило. Новое значение заменяет прежнюю cache запись, IPRESOLVE может исключить несовместимое семейство. Это влияет также на общий multi-cache и redirects, в отличие от CONNECT_TO. URL host/SNI/проверка сертификата сохраняются; так можно направить своё доменное имя на тестовый IP.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.21.3. Native API: libcurl 7.21.3.

PHP: CURLOPT_RESOLVE; libcurl: CURLOPT_RESOLVE

CURLOPT_TCP_FASTOPEN
Тип самой константы: int

Просить ОС использовать TCP Fast Open: отправка данных во время установления соединения может сэкономить RTT. Нужна поддержка ОС, сервера и сети; фильтры могут ломать такой обмен. В документации libcurl отдельно указано взаимодействие: TLS session caching не работает при этой опции. Это не универсальный переключатель ускорения.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.49.0. Native API: libcurl 7.49.0.

PHP: CURLOPT_TCP_FASTOPEN; libcurl: CURLOPT_TCP_FASTOPEN

CURLOPT_TCP_KEEPALIVE
Тип самой константы: int

Включить TCP keepalive probes на новых TCP-соединениях, чтобы ОС проверяла живость простаивающего peer. Параметры KEEP_IDLE/INTERVAL задаются TCP_KEEPIDLE/TCP_KEEPINTVL, количество — TCP_KEEPCNT. Это не HTTP keep-alive и не общий лимит времени запроса; поддержка деталей зависит от ОС.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.25.0. Native API: libcurl 7.25.0.

PHP: CURLOPT_TCP_KEEPALIVE; libcurl: CURLOPT_TCP_KEEPALIVE

CURLOPT_TCP_KEEPCNT
Тип самой константы: int

Количество неотвеченных TCP keepalive probes до признания соединения неработоспособным. Нужен TCP_KEEPALIVE; доступно с PHP 8.4/libcurl 8.9, зависит от ОС. Значения ограничиваются диапазоном системного счётчика, а не дают точное обещание времени отказа.

Значение/результат: int: количество probes.

По умолчанию: 9.

Версии: Доступно с PHP 8.4.0 и libcurl 8.9.0. Native API: libcurl 8.9.0.

PHP: CURLOPT_TCP_KEEPCNT; libcurl: CURLOPT_TCP_KEEPCNT

CURLOPT_TCP_KEEPIDLE
Тип самой константы: int

Сколько соединение простаивает до первых TCP keepalive probes, если TCP_KEEPALIVE включён. Применяется к новым соединениям; конкретная ОС может округлять/ограничивать значение или не поддерживать настройку. Native верхний предел 2147483648 не отменяет диапазон PHP int/C long в целевой сборке.

Значение/результат: int: секунды.

По умолчанию: 60.

Версии: Доступно с libcurl 7.25.0. Native API: libcurl 7.25.0.

PHP: CURLOPT_TCP_KEEPIDLE; libcurl: CURLOPT_TCP_KEEPIDLE

CURLOPT_TCP_KEEPINTVL
Тип самой константы: int

Промежуток между TCP keepalive probes при включённом TCP_KEEPALIVE. Это не интервал повторных HTTP-запросов. Ограничения/поддержка ОС и native диапазона такие же, как у TCP_KEEPIDLE.

Значение/результат: int: секунды.

По умолчанию: 60.

Версии: Доступно с libcurl 7.25.0. Native API: libcurl 7.25.0.

PHP: CURLOPT_TCP_KEEPINTVL; libcurl: CURLOPT_TCP_KEEPINTVL

CURLOPT_TCP_NODELAY
Тип самой константы: int

Выключить алгоритм Nagle, чтобы не задерживать малые TCP-записи ради объединения. Применяется при создании соединения; уже открытое соединение повторно не перенастраивается. Может уменьшить задержку, увеличив число малых пакетов. Значение по умолчанию стало true с libcurl 7.50.

Значение/результат: bool.

По умолчанию: true в текущем libcurl.

Версии: Доступно с libcurl 7.11.2. Native API: libcurl 7.11.2.

PHP: CURLOPT_TCP_NODELAY; libcurl: CURLOPT_TCP_NODELAY

CURLOPT_UNIX_SOCKET_PATH
Тип самой константы: int

Путь Unix domain socket вместо TCP/DNS, например для локального HTTP-сервиса. URL всё ещё задаёт HTTP host/path. При таком пути обычный proxy/TCP маршрут не применяется. Длина пути ограничена ОС (часто до 107 байт); ABSTRACT_UNIX_SOCKET задаёт альтернативный вид того же адреса. На Windows нужна отдельная поддержка сборки/ОС.

Значение/результат: string|null.

По умолчанию: null: обычное соединение.

Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0. Native API: libcurl 7.40.0.

PHP: CURLOPT_UNIX_SOCKET_PATH; libcurl: CURLOPT_UNIX_SOCKET_PATH

CURL_IPRESOLVE_V4
Тип самой константы: int

Ограничить соединение/выбор из pool адресами IPv4.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.8.

PHP: CURL_IPRESOLVE_V4; libcurl: CURLOPT_IPRESOLVE

CURL_IPRESOLVE_V6
Тип самой константы: int

Ограничить соединение/выбор из pool адресами IPv6; при отсутствии IPv6 маршрут может отказать.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.8.

PHP: CURL_IPRESOLVE_V6; libcurl: CURLOPT_IPRESOLVE

CURL_IPRESOLVE_WHATEVER
Тип самой константы: int

Допустить семейства адресов, поддерживаемые системой; применяется к новому соединению и выбору из pool.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.8.

PHP: CURL_IPRESOLVE_WHATEVER; libcurl: CURLOPT_IPRESOLVE

HTTP-аутентификация и credentials

Метод HTTP-аутентификации, сами учётные данные и разрешение передавать их после redirect — независимые решения. Имя опции со словом SAFE не заменяет проверенный TLS. NETRC читает credentials из файла на сервере PHP, а не из компьютера посетителя.

Сначала договоритесь с сервером о способе аутентификации, затем задавайте credentials. Bitmask перечисляет допустимые способы, но не шифрует пароль. Пример показывает только выбор: секрет и адрес не нужны, потому что запрос не выполняется.

Разрешённые методы входа
  1. BASIC — один бит
  2. DIGEST — другой бит
  3. | разрешает оба
  4. & проверяет, что BASIC входит в маску
  5. HTTPAUTH получает готовую маску

Этот вариант. Это демонстрация битов, а не рекомендация включать лишние методы. В рабочем HTTPS API задайте конкретный контракт сервиса: например Bearer и XOAUTH2_BEARER. Наличие BASIC в маске не означает, что сервер выбрал его; фактическое согласование требует запроса.

Прочитать и установить маску методовСамостоятельный пример
<?php
declare(strict_types=1);

$allowed = CURLAUTH_BASIC | CURLAUTH_DIGEST;
echo ($allowed & CURLAUTH_BASIC) !== 0 ? "Basic разрешён политикой\n" : "Basic запрещён\n";
$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
if (!curl_setopt($handle, CURLOPT_HTTPAUTH, $allowed)) throw new RuntimeException('Методы не приняты');
echo "Credentials ещё не заданы; запрос не отправлен\n";
Ожидаемый результат
Basic разрешён политикой
Credentials ещё не заданы; запрос не отправлен
КонстантаНазначение, договор и границы
CURLAUTH_ANY
Тип самой константы: int

Разрешить libcurl выбрать подходящий из доступных HTTP-методов аутентификации; согласование иногда требует дополнительного обмена. Это не разрешение отправлять секреты любому redirect-адресу.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLAUTH_ANY; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_ANYSAFE
Тип самой константы: int

То же, но исключает Basic. Название SAFE не является гарантией современной криптографической безопасности всех остальных алгоритмов; TLS и политика сервиса всё равно нужны.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLAUTH_ANYSAFE; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_AWS_SIGV4
Тип самой константы: int

Выбрать AWS Signature Version 4; параметры provider/region/service задаёт CURLOPT_AWS_SIGV4, учётные данные — username/password. Это подпись запроса, а не формат Bearer.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.75.0.

PHP: CURLAUTH_AWS_SIGV4; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_BASIC
Тип самой константы: int

HTTP Basic: имя и пароль кодируются, но не шифруются самим методом. Передавайте только через проверенный TLS. Это default HTTPAUTH libcurl.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLAUTH_BASIC; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_BEARER
Тип самой константы: int

HTTP Bearer, например OAuth2 access token; токен задаётся XOAUTH2_BEARER. Владение токеном даёт доступ, поэтому не печатайте его и используйте TLS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0.

PHP: CURLAUTH_BEARER; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_DIGEST
Тип самой константы: int

HTTP Digest: ответ на challenge вместо передачи самого пароля как Basic. Поддержка и вариант алгоритма зависят от сервера/сборки; это не замена TLS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLAUTH_DIGEST; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_DIGEST_IE
Тип самой константы: int

Исторический вариант Digest для Internet Explorer. Современная libcurl трактует бит как обычный DIGEST; отдельное IE-поведение больше не поддерживается.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.19.3.

PHP: CURLAUTH_DIGEST_IE; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_GSSAPI
Тип самой константы: int

GSS-API-аутентификация, в частности разрешённый бит SOCKS5_AUTH. Требует подходящего GSS-API backend; не смешивайте его с HTTP Basic по одному названию auth.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.1

PHP: CURLAUTH_GSSAPI; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_GSSNEGOTIATE
Тип самой константы: int

Старое имя HTTP Negotiate; современное соответствующее имя — CURLAUTH_NEGOTIATE. Это алгоритм согласования, не пароль.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLAUTH_GSSNEGOTIATE; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_NEGOTIATE
Тип самой константы: int

HTTP Negotiate/SPNEGO; требует GSS-API либо SSPI на Windows и настроенного окружения. Сам флаг не создаёт Kerberos-билет.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.38.0.

PHP: CURLAUTH_NEGOTIATE; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_NONE
Тип самой константы: int

Нулевая маска: без аутентификации. Для SOCKS5 это разрешение только no-auth; ноль не добавляет отдельный бит к другим алгоритмам.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.6.

PHP: CURLAUTH_NONE; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_NTLM
Тип самой константы: int

Историческая Microsoft NTLM challenge-response схема; использует слабые криптографические механизмы. Для нового протокола выбирайте согласованный современный способ.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLAUTH_NTLM; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_NTLM_WB
Тип самой константы: int

Исторический NTLM через внешнюю winbind/ntlm_auth программу. Поддержка удалена из libcurl 8.8.0, хотя PHP-константа может остаться. Старый механизм мог создавать дочерний процесс и SIGCHLD на POSIX.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.22.0

PHP: CURLAUTH_NTLM_WB; libcurl: CURLOPT_HTTPAUTH

CURLAUTH_ONLY
Тип самой константы: int

Метабит: объединяется | с одним конкретным HTTP auth-методом, чтобы после проверки без аутентификации принимать только этот алгоритм. Сам по себе не является алгоритмом и не означает ANY.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.3.

PHP: CURLAUTH_ONLY; libcurl: CURLOPT_HTTPAUTH

CURLGSSAPI_DELEGATION_FLAG
Тип самой константы: int

Разрешить безусловное делегирование GSS-API credentials. Это расширяет полномочия сервера и требует сознательной политики доверия.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.22.0.

PHP: CURLGSSAPI_DELEGATION_FLAG; libcurl: CURLOPT_GSSAPI_DELEGATION

CURLGSSAPI_DELEGATION_POLICY_FLAG
Тип самой константы: int

Делегировать только при OK-AS-DELEGATE в service ticket, если библиотека GSS-API и compile-time флаг GSS_C_DELEG_POLICY_FLAG поддерживаются.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.22.0.

PHP: CURLGSSAPI_DELEGATION_POLICY_FLAG; libcurl: CURLOPT_GSSAPI_DELEGATION

CURLOPT_AWS_SIGV4
Тип самой константы: int

Строка provider1[:provider2[:region[:service]]] настраивает AWS V4 HTTP(S) подпись. Providers формируют имена алгоритма/заголовков; при пропущенных region/service они извлекаются из host URL. Установка заменяет HTTPAUTH на AWS_SIGV4, не комбинируется с другими видами входа; бит CURLAUTH_AWS_SIGV4 эквивалентен "aws:amz". Credentials задаются отдельно; сам setopt не доказывает правильности подписи. null отключает эту настройку.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 8.2.0 и libcurl 7.75.0. Native API: libcurl 7.75.0.

PHP: CURLOPT_AWS_SIGV4; libcurl: CURLOPT_AWS_SIGV4

CURLOPT_DISALLOW_USERNAME_IN_URL
Тип самой константы: int

Запрещает userinfo с именем пользователя в CURLOPT_URL. Помогает не смешивать URL и credentials, но не заменяет проверку схемы, адреса, порта и redirect. В native действует на CURLOPT_URL, не на отдельный CURLOPT_CURLU API.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0. Native API: libcurl 7.61.0.

PHP: CURLOPT_DISALLOW_USERNAME_IN_URL; libcurl: CURLOPT_DISALLOW_USERNAME_IN_URL

CURLOPT_GSSAPI_DELEGATION
Тип самой константы: int

Разрешить серверу использовать делегированные credentials: FLAG безусловно, POLICY_FLAG только с OK-AS-DELEGATE и поддержкой GSS_C_DELEG_POLICY_FLAG при сборке. По умолчанию делегирование выключено с7.21.7. CURLGSSAPI_DELEGATION_NONE встречается в native-документации, но PHP8.5.11 его не экспортирует: для выключения0.

Значение/результат: int-маска.

По умолчанию: 0: NONE (native-имя).

Версии: Доступно с libcurl 7.22.0. Native API: libcurl 7.22.0.

PHP: CURLOPT_GSSAPI_DELEGATION; libcurl: CURLOPT_GSSAPI_DELEGATION

CURLOPT_HTTPAUTH
Тип самой константы: int

Разрешённые способы HTTP-входа; при нескольких libcurl узнаёт предложения сервера и выбирает подходящий, иногда с дополнительным round-trip. Username/password отдельно USERPWD или USERNAME/PASSWORD, Bearer — XOAUTH2_BEARER. ANY включает все, ANYSAFE лишь исключает BASIC и не гарантирует современную криптографическую безопасность. AWS_SIGV4 имеет отдельный контракт. Собственный Authorization в HTTPHEADER может конфликтовать; для proxy существует PROXYAUTH.

Значение/результат: int-маска CURLAUTH_*.

По умолчанию: BASIC.

Версии: Доступно с libcurl 7.10.6. Native API: libcurl 7.10.6.

PHP: CURLOPT_HTTPAUTH; libcurl: CURLOPT_HTTPAUTH

CURLOPT_KEYPASSWD
Тип самой константы: int

Пароль приватного ключа SSLKEY либо SSH_PRIVATE_KEYFILE; это не пароль удалённой учётной записи. Для публичного сертификата пароль обычно не нужен, для зашифрованного private key — нужен. null сбрасывает; не включать значение в журналы.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0.

PHP: CURLOPT_KEYPASSWD; libcurl: CURLOPT_KEYPASSWD

CURLOPT_LOGIN_OPTIONS
Тип самой константы: int

Протокольные login параметры вместе с USERNAME, например AUTH=NTLM либо AUTH=*. IMAP AUTH=+LOGIN с8.2 принудительно использует plain LOGIN вместо SASL; сервер может запретить, а без TLS пароль раскрывается. Настройка влияет на новый login, но сама по себе не меняет security context и не гарантирует отказ от reuse соединения, созданного с другими login options.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.0.7 и libcurl 7.34.0. Native API: libcurl 7.34.0.

PHP: CURLOPT_LOGIN_OPTIONS; libcurl: CURLOPT_LOGIN_OPTIONS

CURLOPT_NETRC
Тип самой константы: int

Управляет поиском credentials .netrc относительно userinfo URL; явные USERPWD/USERNAME имеют больший приоритет. OPTIONAL предпочитает URL, REQUIRED игнорирует URL credentials. С8.16 путь может задаваться NETRC environment; Windows ищет %HOME% затем %USERPROFILE%, .netrc затем _netrc; NETRC_FILE задаёт явный путь. Записи привязаны к host без protocol/port. Формат machine name login user password secret; default один и после machine, macdef пропускается. С7.84 поддерживаются quoted strings с экранированием. libcurl не проверяет приватность прав файла; её обеспечивает приложение.

Значение/результат: int CURL_NETRC_IGNORED|OPTIONAL|REQUIRED.

По умолчанию: IGNORED.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_NETRC; libcurl: CURLOPT_NETRC

CURLOPT_NETRC_FILE
Тип самой константы: int

Файл credentials вместо домашнего .netrc; работает с выбранным NETRC mode, сам по себе не включает чтение. Последний путь заменяет прежний. Секреты не должны попадать в web-root, общий архив примеров или репозиторий.

Значение/результат: string|null: полный путь.

По умолчанию: null.

Версии: Доступно с libcurl 7.11.0. Native API: libcurl 7.11.0.

PHP: CURLOPT_NETRC_FILE; libcurl: CURLOPT_NETRC_FILE

CURLOPT_PASSWORD
Тип самой константы: int

Пароль remote-аутентификации вместе с USERNAME. Не URL-decode автоматически как часть USERPWD; отдельный параметр удобен для двоеточий. null сбрасывает. Не равен passphrase приватного ключа KEYPASSWD.

Значение/результат: string|null.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1.

PHP: CURLOPT_PASSWORD; libcurl: CURLOPT_PASSWORD

CURLOPT_SASL_AUTHZID
Тип самой константы: int

Authorization identity для PLAIN SASL, отдельно от authentication identity USERNAME. Например разрешённый общий почтовый ящик. Если не задана, сервер выводит authzid из authcid. Не предоставляет дополнительные права сам по себе: сервер обязан разрешить доступ.

Значение/результат: string|null.

По умолчанию: не задан.

Версии: Доступно с PHP 8.2.0 и libcurl 7.66.0. Native API: libcurl 7.66.0.

PHP: CURLOPT_SASL_AUTHZID; libcurl: CURLOPT_SASL_AUTHZID

CURLOPT_SASL_IR
Тип самой константы: int

Послать initial response в первом SASL auth packet для сокращения round-trips; подходит Login,Plain,GSSAPI,NTLM,OAuth2 механизмам. IMAP может определить поддержку по SASL-IR CAPABILITY без явного флага. Не отменяет необходимость защищённого транспорта.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.31.0. Native API: libcurl 7.31.0.

PHP: CURLOPT_SASL_IR; libcurl: CURLOPT_SASL_IR

CURLOPT_SERVICE_NAME
Тип самой константы: int

Имя сервиса DIGEST-MD5/SPNEGO/Kerberos5 аутентификации. Не URL и не отображаемое имя учётной записи. Для proxy есть отдельное PROXY_SERVICE_NAME.

Значение/результат: string|null.

По умолчанию: ftp/HTTP/imap/ldap/pop/smtp по протоколу.

Версии: Доступно с PHP 7.0.7 и libcurl 7.43.0. Native API: libcurl 7.43.0.

PHP: CURLOPT_SERVICE_NAME; libcurl: CURLOPT_SERVICE_NAME

CURLOPT_UNRESTRICTED_AUTH
Тип самой константы: int

При FOLLOWLOCATION разрешить передавать учётные данные и явно заданный Cookie также на другой host/scheme/port. Это может раскрыть секрет постороннему redirect-адресату. Другие пользовательские HTTPHEADER-заголовки вообще не получают автоматическую защиту только от выключения этой опции. Для API безопаснее проверять каждый redirect и доверенные адреса.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.10.4. Native API: libcurl 7.10.4.

PHP: CURLOPT_UNRESTRICTED_AUTH; libcurl: CURLOPT_UNRESTRICTED_AUTH

CURLOPT_USERNAME
Тип самой константы: int

Имя для аутентификации вместе с PASSWORD; в отличие от USERPWD может содержать двоеточие. Для Windows-доменов возможны DOMAIN\user/UPN в зависимости от схемы. SSPI может использовать текущие учётные данные; такой выбор должен быть явным. Смена пользователя и повторное использование соединения имеют особенности конкретного протокола.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1.

PHP: CURLOPT_USERNAME; libcurl: CURLOPT_USERNAME

CURLOPT_USERPWD
Тип самой константы: int

Имя и пароль, разделённые первым двоеточием; строка не URL-декодируется. Если двоеточие необходимо в имени, задайте USERNAME/PASSWORD отдельно. HTTPAUTH выбирает способ, LOGIN_OPTIONS уточняет отдельные почтовые протоколы. Не вставляйте секреты в URL или исходники примера; TLS и политика redirect обязательны независимо от удобного формата строки.

Значение/результат: string|null: user:password.

По умолчанию: null.

Версии: Native API: libcurl 7.1.

PHP: CURLOPT_USERPWD; libcurl: CURLOPT_USERPWD

CURLOPT_XOAUTH2_BEARER
Тип самой константы: int

OAuth2 access token. Для HTTP выбирают HTTPAUTH=CURLAUTH_BEARER; для IMAP/LDAP/POP3/SMTP нужны протокольные условия и USERNAME. libcurl не получает и не обновляет токен самостоятельно. Строка секретна: TLS, ограниченные права и отсутствие token в логах необходимы.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.0.7 и libcurl 7.33.0. Native API: libcurl 7.33.0.

PHP: CURLOPT_XOAUTH2_BEARER; libcurl: CURLOPT_XOAUTH2_BEARER

CURL_NETRC_IGNORED
Тип самой константы: int

Не читать .netrc, default. Не означает «запретить все учётные данные», если они заданы другими опциями.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_NETRC_IGNORED; libcurl: CURLOPT_NETRC

CURL_NETRC_OPTIONAL
Тип самой константы: int

Использовать .netrc при необходимости, отдавая приоритет данным из URL; явно заданные USERPWD/USERNAME имеют свой более высокий приоритет.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_NETRC_OPTIONAL; libcurl: CURLOPT_NETRC

CURL_NETRC_REQUIRED
Тип самой константы: int

Требовать .netrc и игнорировать credentials из URL; файл выбирается NETRC_FILE/окружением/домашним каталогом. За права доступа к секретному файлу отвечает приложение/владелец.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_NETRC_REQUIRED; libcurl: CURLOPT_NETRC

TLS: доверие, имя, сертификаты и версии

Сертификат сервера и клиентский сертификат имеют разные роли. CAINFO/CAPATH задают, кому доверять; SSLCERT/SSLKEY подтверждают клиента при mTLS. Backend OpenSSL, Schannel, GnuTLS, Rustls и другие поддерживают разные параметры и форматы. Не переносите опцию между ними только по наличию PHP-константы.

Проверенный TLS решает две задачи: подтверждает доверие цепочке сертификата и соответствие имени адресату. Они включаются раздельно. Исправление неизвестного CA — настройка доверенного хранилища, а не отключение проверки. Версия TLS задаёт допустимый диапазон, а не гарантированно выбранный протокол.

Политика будущего TLS-соединения
  1. VERIFYPEER=true → доверенная цепочка
  2. VERIFYHOST=2 → нужное имя сервера
  3. TLSv1_2 | MAX_TLSv1_3 → диапазон 1.2…1.3
  4. Реальное согласование произойдёт при curl_exec

Этот вариант. | объединяет нижнюю и верхнюю границы именно по договору SSLVERSION. Вызов не проверял сертификат и не доказывает, что сервер поддерживает диапазон: передачи нет. Пример предполагает современную сборку TLS. В обычном приложении актуальный безопасный default backend часто удобнее жёсткой верхней границы.

Настроить проверки и диапазон TLSСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
$range = CURL_SSLVERSION_TLSv1_2 | CURL_SSLVERSION_MAX_TLSv1_3;
if (!curl_setopt_array($handle, [
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_SSLVERSION => $range,
])) throw new RuntimeException('TLS-политика не поддержана');
echo "Проверки включены; запрошен диапазон TLS 1.2–1.3\n";
Ожидаемый результат
Проверки включены; запрошен диапазон TLS 1.2–1.3
КонстантаНазначение, договор и границы
CURLOPT_CAINFO
Тип самой константы: int

Файл одного или нескольких доверенных CA для VERIFYPEER. Предпочитать явный абсолютный путь; не путать с клиентским сертификатом SSLCERT. Schannel обычно использует Windows root store, поддержка CAINFO появилась для Windows7, native рекомендует Windows8+. LDAP: применимо к OpenLDAP через libcurl, не к Apple fork; WinLDAP использует Windows CA store. CURLINFO_CAINFO сообщает встроенный default, не обязательно пользовательский путь.

Значение/результат: string|null: путь к файлу.

По умолчанию: сборка/система; PHP curl.cainfo может переопределить.

Версии: Доступно с libcurl 7.4.2. Native API: libcurl 7.4.2.

PHP: CURLOPT_CAINFO; libcurl: CURLOPT_CAINFO

CURLOPT_CAINFO_BLOB
Тип самой константы: int

CA certificates из памяти вместо файла; в PHP передаётся строка, а не C curl_blob. Имеет приоритет над CAINFO. Работает при включённой проверке сертификатов; строки сертификатов не заменяют проверку имени VERIFYHOST.

Значение/результат: string: PEM-байты.

По умолчанию: не задан.

Версии: Доступно с PHP 8.2.0 и libcurl 7.77.0. Native API: libcurl 7.77.0.

PHP: CURLOPT_CAINFO_BLOB; libcurl: CURLOPT_CAINFO_BLOB

CURLOPT_CAPATH
Тип самой константы: int

Каталог CA для VERIFYPEER. OpenSSL ожидает подготовленные hash-ссылки/имена через c_rehash; просто собрать произвольные файлы в папку недостаточно. Native-документация отмечает ограничение OpenSSL CAPATH на Windows: проверять backend, для воспроизводимого Windows-примера проще CAINFO-файл. CURLINFO_CAPATH — встроенный default.

Значение/результат: string|null: каталог.

По умолчанию: определён при сборке.

Версии: Доступно с libcurl 7.9.8. Native API: libcurl 7.9.8.

PHP: CURLOPT_CAPATH; libcurl: CURLOPT_CAPATH

CURLOPT_CA_CACHE_TIMEOUT
Тип самой константы: int

Время хранения построенного в памяти CA store для повторных соединений; CAINFO может загружаться дорого. 0 выключает кеш, -1 сохраняет без срока. После истечения новый запрос перечитывает store. Длительный кеш задерживает применение изменившегося файла CA; не смешивать с DNS timeout.

Значение/результат: int, секунды.

По умолчанию: 86400.

Версии: Доступно с PHP 8.3.0 и libcurl 7.87.0 Native API: libcurl 7.87.0.

PHP: CURLOPT_CA_CACHE_TIMEOUT; libcurl: CURLOPT_CA_CACHE_TIMEOUT

CURLOPT_CERTINFO
Тип самой константы: int

Включает сбор сведений о цепочке сертификатов для последующего CURLINFO_CERTINFO. Это не настройка доверия и не требование печатать сертификаты. Старая формулировка PHP constants о STDERR и обязательном VERBOSE не описывает текущий native механизм: VERBOSE для получения массива не нужен.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1.

PHP: CURLOPT_CERTINFO; libcurl: CURLOPT_CERTINFO

CURLOPT_CRLFILE
Тип самой константы: int

Файл списка отзыва CRL для проверки цепочки при TLS/VERIFYPEER. OpenSSL включает CRL_CHECK и CRL_CHECK_ALL для всей цепочки; с7.71 настройка также подразумевает NO_PARTIALCHAIN из-за OpenSSL bug. GnuTLS не даёт отдельно влиять на применение переданного CRL. Не читаемый CRL даёт SSL_CRL_BADFILE, а найденный отзыв — ошибку проверки сертификата, не обязательно тот же код.

Значение/результат: string|null: PEM-файл.

По умолчанию: null.

Версии: Доступно с libcurl 7.19.0. Native API: libcurl 7.19.0.

PHP: CURLOPT_CRLFILE; libcurl: CURLOPT_CRLFILE

CURLOPT_ISSUERCERT
Тип самой константы: int

Дополнительная проверка, что серверный сертификат выдан указанным issuer. Полезно для нужной ветви PKI. Сам переданный issuer не становится доверенным автоматически; требуется VERIFYPEER. Без неё неуспех этой проверки не считается отказом. Несовпадение может дать SSL_ISSUER_ERROR.

Значение/результат: string|null: PEM-файл.

По умолчанию: null.

Версии: Доступно с libcurl 7.19.0. Native API: libcurl 7.19.0.

PHP: CURLOPT_ISSUERCERT; libcurl: CURLOPT_ISSUERCERT

CURLOPT_ISSUERCERT_BLOB
Тип самой константы: int

Тот же дополнительный issuer check из памяти вместо файла. PHP принимает строку, не curl_blob. Не заменяет CA trust и VERIFYPEER; без неё результат не становится отказом соединения. Предъявленный issuer не проверяется как доверенный сам по себе.

Значение/результат: string: PEM-байты.

По умолчанию: не задан.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_ISSUERCERT_BLOB; libcurl: CURLOPT_ISSUERCERT_BLOB

CURLOPT_PINNEDPUBLICKEY
Тип самой константы: int

Публичный ключ сервера: путь PEM/DER либо "sha256//base64;sha256//base64". Ключ извлекается из TLS-сертификата; несовпадение даёт SSL_PINNEDPUBKEYNOTMATCH до прикладного обмена. Независим от VERIFYPEER, но не повод её выключать. В актуальном native pin относится к первоначальному origin, не ко всем чужим origin после redirect. LDAP применимо к OpenLDAP через libcurl, не Apple fork; нужна поддержка backend и план ротации ключей.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.0.7 и libcurl 7.39.0. Native API: libcurl 7.39.0.

PHP: CURLOPT_PINNEDPUBLICKEY; libcurl: CURLOPT_PINNEDPUBLICKEY

CURLOPT_SSLCERT
Тип самой константы: int

Файл клиентского TLS-сертификата, обычно PEM с отдельным SSLKEY; тип меняет SSLCERTTYPE. Schannel может выбрать store-путь location\store\thumbprint, например CurrentUser\MY\thumbprint, или P12. Поддержанные store locations: CurrentUser,LocalMachine,CurrentService,Services,CurrentUserGroupPolicy,LocalMachineGroupPolicy,LocalMachineEnterprise. Не путать клиентский сертификат с CAINFO доверенных серверов.

Значение/результат: string|null:клиентский сертификат.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_SSLCERT; libcurl: CURLOPT_SSLCERT

CURLOPT_SSLCERTTYPE
Тип самой константы: int

Формат клиентского cert:PEM/DER согласно backend, P12 у OpenSSL/Schannel, у GnuTLS с 8.11. PHP исторически также перечисляет ENG; это не переносимый формат файла во всех backend. Тип должен соответствовать байтам и возможности сборки.

Значение/результат: string.

По умолчанию: PEM.

Версии: Доступно с libcurl 7.9.3. Native API: libcurl 7.9.3.

PHP: CURLOPT_SSLCERTTYPE; libcurl: CURLOPT_SSLCERTTYPE

CURLOPT_SSLCERT_BLOB
Тип самой константы: int

Клиентский сертификат из памяти:Schannel P12,OpenSSL PEM/P12,mbedTLS PEM/DER,Rustls PEM; формат задаётся SSLCERTTYPE. PHP принимает строку, не curl_blob. Не заменяет приватный ключ и не используется как CA store.

Значение/результат: string:байты клиентского сертификата.

По умолчанию: не задан.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_SSLCERT_BLOB; libcurl: CURLOPT_SSLCERT_BLOB

CURLOPT_SSLENGINE
Тип самой константы: int

Идентификатор cryptoengine/provider для приватного ключа. OpenSSL 1 использовал engines,OpenSSL 3 providers; в текущем native provider может иметь property после двоеточия. Нужно соответствующее окружение и формат SSLKEYTYPE; произвольное имя не создаёт provider.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.9.3. Native API: libcurl 7.9.3.

PHP: CURLOPT_SSLENGINE; libcurl: CURLOPT_SSLENGINE

CURLOPT_SSLENGINE_DEFAULT
Тип самой константы: int

Сделать уже выбранный SSLENGINE default для асимметричных операций; прежде задаётся SSLENGINE. PHP constants называет значение строковым идентификатором, и PHP 8.5 wrapper действительно маршрутизирует опцию через string ветку, тогда как native API документирует long 1. Поэтому не предлагаем переносимый пример с этой несогласованностью; выбор engine/provider проверяют в целевой сборке, имя назначается через SSLENGINE.

Значение/результат: исторический PHP string bridge; native long 1.

По умолчанию: не назначен.

Версии: Доступно с libcurl 7.9.3. Native API: libcurl 7.9.3.

PHP: CURLOPT_SSLENGINE_DEFAULT; libcurl: CURLOPT_SSLENGINE_DEFAULT

CURLOPT_SSLKEY
Тип самой константы: int

Приватный ключ клиентского TLS-сертификата; формат SSLKEYTYPE,passphrase KEYPASSWD. Schannel игнорирует отдельный файл, ожидая ключ в certificate-store/P12. Не передавать путь из непроверенного HTTP ввода.

Значение/результат: string|null:файл приватного ключа.

По умолчанию: null;формат PEM.

Версии: Доступно с libcurl 7.9.3. Native API: libcurl 7.9.3.

PHP: CURLOPT_SSLKEY; libcurl: CURLOPT_SSLKEY

CURLOPT_SSLKEYTYPE
Тип самой константы: int

Формат приватного ключа:PEM,DER,ENG,PROV. DER не работает с OpenSSL; ENG использует SSLKEY как идентификатор выбранного SSLENGINE; PROV(с 8.12) — provider. Это не выбор шифра TLS.

Значение/результат: string.

По умолчанию: PEM.

Версии: Доступно с libcurl 7.9.3. Native API: libcurl 7.9.3.

PHP: CURLOPT_SSLKEYTYPE; libcurl: CURLOPT_SSLKEYTYPE

CURLOPT_SSLKEY_BLOB
Тип самой константы: int

Приватный ключ из памяти вместо SSLKEY файла; поддержка OpenSSL/Rustls,формат SSLKEYTYPE. Строка секретна, её длина и тип не подтверждают пригодности ключа.

Значение/результат: string:байты приватного ключа.

По умолчанию: не задан.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_SSLKEY_BLOB; libcurl: CURLOPT_SSLKEY_BLOB

CURLOPT_SSLVERSION
Тип самой константы: int

Диапазон TLS, а не одно точное значение:TLSv1_2 означает 1.2 или новее. DEFAULT с 8.16 минимум 1.2(backend может быть строже); MAX_DEFAULT с 7.61 обычно 1.3,раньше 1.2. SSLv2/SSLv3 текущий libcurl отвергает. Для верхней границы объединить min и MAX через |; настройки не порождают поддержку версии в backend.

Значение/результат: int: минимум TLS | необязательный максимум.

По умолчанию: DEFAULT.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_SSLVERSION; libcurl: CURLOPT_SSLVERSION

CURLOPT_SSL_CIPHER_LIST
Тип самой константы: int

Разрешённые наборы шифров для TLS 1.2 и более старых версий. У OpenSSL названия разделяют двоеточием; поддерживаются также операторы выбора. Schannel задаёт алгоритмы, GnuTLS использует собственную priority string: одинаковая строка не переносима между backend. TLS 1.3 настраивается отдельно через TLS13_CIPHERS. null возвращает встроенный выбор.

Значение/результат: string|null.

По умолчанию: список TLS backend.

Версии: Доступно с libcurl 7.9. Native API: libcurl 7.9.

PHP: CURLOPT_SSL_CIPHER_LIST; libcurl: CURLOPT_SSL_CIPHER_LIST

CURLOPT_SSL_EC_CURVES
Тип самой константы: int

Разрешённые эллиптические кривые/группы обмена ключами, например X25519:P-521. Это не список шифров или сертификатов. Набор имён зависит от TLS backend; null возвращает его стандартный выбор. Слишком узкий список может лишить клиента совместимого обмена ключами.

Значение/результат: string|null.

По умолчанию: встроенный список backend.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0. Native API: libcurl 7.73.0.

PHP: CURLOPT_SSL_EC_CURVES; libcurl: CURLOPT_SSL_EC_CURVES

CURLOPT_SSL_ENABLE_ALPN
Тип самой константы: int

Согласование прикладного протокола при TLS handshake, например HTTP/2 через ALPN. Требует поддержки TLS backend и соответствующего HTTP-протокола в libcurl. Отключение может лишить HTTPS соединение HTTP/2, но не меняет проверку сертификата.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с PHP 7.0.7 и libcurl 7.36.0. Native API: libcurl 7.36.0.

PHP: CURLOPT_SSL_ENABLE_ALPN; libcurl: CURLOPT_SSL_ENABLE_ALPN

CURLOPT_SSL_OPTIONS
Тип самой константы: int

Дополнительные политики TLS: ALLOW_BEAST, NO_REVOKE, NO_PARTIALCHAIN, REVOKE_BEST_EFFORT, NATIVE_CA, AUTO_CLIENT_CERT. Объединяют только осознанно выбранные биты через |. Поддержка зависит от backend/версии, некоторые биты снижают защиту или раскрывают клиентский сертификат. Для HTTPS proxy отдельная PROXY_SSL_OPTIONS; описание каждого бита находится в группе TLS-политик.

Значение/результат: int: маска CURLSSLOPT_*.

По умолчанию: 0.

Версии: Доступно с PHP 7.0.7. Native API: libcurl 7.25.0.

PHP: CURLOPT_SSL_OPTIONS; libcurl: CURLOPT_SSL_OPTIONS

CURLOPT_SSL_SESSIONID_CACHE
Тип самой константы: int

Сохранять данные TLS-сессий для возобновления handshake. Это не HTTP cookie и не сам пул открытых соединений. Отключение иногда помогает диагностировать несовместимый TLS backend, но лишает ускорения; сервер также может отказаться от возобновления.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с libcurl 7.16.0. Native API: libcurl 7.16.0.

PHP: CURLOPT_SSL_SESSIONID_CACHE; libcurl: CURLOPT_SSL_SESSIONID_CACHE

CURLOPT_SSL_VERIFYHOST
Тип самой константы: int

Проверять, что имя/адрес из URL соответствует сертификату (SAN, либо допустимый CN). 0 выключает проверку и небезопасен. Значение 1 было диагностическим до 7.28.0, ошибкой в 7.28.1–7.65.3, эквивалентно 2 с 7.66; используйте 2. Wildcard разрешён в крайней левой части имени, не для одного TLD; IP требует SAN типа IP. Отдельная VERIFYPEER проверяет доверие цепочке. Непроверенное соединение может также наполнить HSTS/Alt-Svc кэш недоверенными данными.

Значение/результат: int: 2 или 0.

По умолчанию: 2.

Версии: Доступно с libcurl 7.8.1. Native API: libcurl 7.8.1.

PHP: CURLOPT_SSL_VERIFYHOST; libcurl: CURLOPT_SSL_VERIFYHOST

CURLOPT_SSL_VERIFYPEER
Тип самой константы: int

Проверка подписи/цепочки сертификата по доверенным CA из CAINFO/CAPATH или backend. false отключает доверительную проверку, а не исправляет корневую причину ошибки; имя проверяет отдельная VERIFYHOST. При отключении CA могут вообще не загружаться. Для LDAP поддержка зависит от OpenLDAP/WinLDAP и версии (WinLDAP с 8.22); Apple OpenLDAP имеет особенности. Шифрование без проверки адресата не подтверждает его подлинность.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с libcurl 7.4.2. Native API: libcurl 7.4.2.

PHP: CURLOPT_SSL_VERIFYPEER; libcurl: CURLOPT_SSL_VERIFYPEER

CURLOPT_SSL_VERIFYSTATUS
Тип самой константы: int

Требовать проверку статуса сертификата через OCSP stapling. При включении отсутствие пригодного stapled response тоже может завершить передачу ошибкой; это не запрос к любому OCSP-серверу средствами PHP. Поддержка зависит от TLS backend. Для LDAP применимость OpenLDAP ограничена и не распространяется автоматически на Apple fork.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.41.0. Native API: libcurl 7.41.0.

PHP: CURLOPT_SSL_VERIFYSTATUS; libcurl: CURLOPT_SSL_VERIFYSTATUS

CURLOPT_TLS13_CIPHERS
Тип самой константы: int

Наборы шифров TLS 1.3 через двоеточие. SSL_CIPHER_LIST управляет TLS 1.2 и старше, поэтому не заменяет эту опцию. Поддержка зависит от backend/версии: старое утверждение «только OpenSSL» не описывает все современные сборки. null возвращает стандартный выбор.

Значение/результат: string|null.

По умолчанию: список TLS backend.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0. Native API: libcurl 7.61.0.

PHP: CURLOPT_TLS13_CIPHERS; libcurl: CURLOPT_TLS13_CIPHERS

CURLSSLOPT_ALLOW_BEAST
Тип самой константы: int

Разрешить старое SSL/TLS-поведение, снижающее защиту от BEAST ради совместимости. Не включать как универсальное исправление TLS; действие зависит от backend.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.25.0

PHP: CURLSSLOPT_ALLOW_BEAST; libcurl: CURLOPT_SSL_OPTIONS

CURLSSLOPT_AUTO_CLIENT_CERT
Тип самой константы: int

Разрешить Schannel автоматически выбрать клиентский сертификат из хранилища Windows. Может раскрывать личность серверам, которым не планировали её передавать; применяется только сознательно. До libcurl 7.77 такое автоматическое предоставление было поведением Schannel по умолчанию.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.77.0

PHP: CURLSSLOPT_AUTO_CLIENT_CERT; libcurl: CURLOPT_SSL_OPTIONS

CURLSSLOPT_NATIVE_CA
Тип самой константы: int

Использовать системные доверенные CA. Поддержка зависит от backend/ОС: OpenSSL на Windows с 7.71, wolfSSL с 8.3 на поддержанных платформах, GnuTLS с 8.5. Rustls с 8.13 использует только native store, исключая другие CA-location настройки; на Linux его native вариант соответствует Mozilla bundle. Поэтому это не одинаковое добавление CA во всех сборках и не отключение проверки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.71.0

PHP: CURLSSLOPT_NATIVE_CA; libcurl: CURLOPT_SSL_OPTIONS

CURLSSLOPT_NO_PARTIALCHAIN
Тип самой константы: int

Не принимать цепочку, которая заканчивается доверенным промежуточным сертификатом вместо корневого. OpenSSL поддерживает это поведение; Schannel с 8.15 — для пользовательских CA. Отличается от VERIFYHOST/VERIFYPEER.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.68.0

PHP: CURLSSLOPT_NO_PARTIALCHAIN; libcurl: CURLOPT_SSL_OPTIONS

CURLSSLOPT_NO_REVOKE
Тип самой константы: int

Отключить проверку отзыва сертификата у Schannel. Это ослабление политики безопасности, а не обычное средство исправить сетевую ошибку CRL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.44.0

PHP: CURLSSLOPT_NO_REVOKE; libcurl: CURLOPT_SSL_OPTIONS

CURLSSLOPT_REVOKE_BEST_EFFORT
Тип самой константы: int

Для Schannel терпеть отсутствие/недоступность источников отзыва, сохраняя отказ при известном отзыве. NO_REVOKE имеет более сильное отключающее действие; не смешивайте их без понимания.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.70.0

PHP: CURLSSLOPT_REVOKE_BEST_EFFORT; libcurl: CURLOPT_SSL_OPTIONS

CURL_SSLVERSION_DEFAULT
Тип самой константы: int

Выбрать стандартный диапазон TLS сборки. С libcurl 8.16.0 минимальный default — TLS1.2, если backend не требует более строгого. Это не обещание одной фиксированной версии на всех серверах.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_DEFAULT; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_MAX_DEFAULT
Тип самой константы: int

Максимум стандартного диапазона: обычно TLS1.3 начиная с libcurl 7.61.0 при поддержке backend; до того был TLS1.2.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0

PHP: CURL_SSLVERSION_MAX_DEFAULT; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_MAX_NONE
Тип самой константы: int

Не задавать отдельное ограничение максимума. Это служебное значение диапазона, не отключение TLS-проверок.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0

PHP: CURL_SSLVERSION_MAX_NONE; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_MAX_TLSv1_0
Тип самой константы: int

Максимальная версия TLS1.0. Это верхняя граница; обычно комбинируется с отдельным минимумом. Не задавайте максимум ниже минимума.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0

PHP: CURL_SSLVERSION_MAX_TLSv1_0; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_MAX_TLSv1_1
Тип самой константы: int

Максимальная версия TLS1.1. Это верхняя граница; обычно комбинируется с отдельным минимумом. Не задавайте максимум ниже минимума.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0

PHP: CURL_SSLVERSION_MAX_TLSv1_1; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_MAX_TLSv1_2
Тип самой константы: int

Максимальная версия TLS1.2. Это верхняя граница; обычно комбинируется с отдельным минимумом. Не задавайте максимум ниже минимума.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0

PHP: CURL_SSLVERSION_MAX_TLSv1_2; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_MAX_TLSv1_3
Тип самой константы: int

Максимальная версия TLS1.3. Это верхняя граница; обычно комбинируется с отдельным минимумом. Не задавайте максимум ниже минимума.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0

PHP: CURL_SSLVERSION_MAX_TLSv1_3; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_SSLv2
Тип самой константы: int

Исторический SSLv2. Современная libcurl отказывает; не использовать для нового соединения.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_SSLv2; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_SSLv3
Тип самой константы: int

Исторический SSLv3. Современная libcurl отказывает; не обходите это отключением проверки сертификата.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_SSLv3; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_TLSv1
Тип самой константы: int

Разрешить TLS1.0 и новее; название не означает «строго TLS1.0». Слишком слабый минимум для нового сервиса.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_TLSv1; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_TLSv1_0
Тип самой константы: int

Минимальная версия TLS1.0; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_TLSv1_0; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_TLSv1_1
Тип самой константы: int

Минимальная версия TLS1.1; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_TLSv1_1; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_TLSv1_2
Тип самой константы: int

Минимальная версия TLS1.2; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_SSLVERSION_TLSv1_2; libcurl: CURLOPT_SSLVERSION

CURL_SSLVERSION_TLSv1_3
Тип самой константы: int

Минимальная версия TLS1.3; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0

PHP: CURL_SSLVERSION_TLSv1_3; libcurl: CURLOPT_SSLVERSION

CURL_TLSAUTH_SRP
Тип самой константы: int

Значение метода TLS-SRP (Secure Remote Password), если он поддерживается TLS backend. Требует TLSAUTH_USERNAME/PASSWORD; наличие константы не гарантирует backend/серверную поддержку. Это native enum; CURLOPT_TLSAUTH_TYPE в PHP ожидает строку "SRP", а не данный int.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.4.

PHP: CURL_TLSAUTH_SRP; libcurl: CURLOPT_TLSAUTH_TYPE

Прокси, SOCKS и отдельный TLS к прокси

Прокси — дополнительный участник пути. При HTTPS proxy могут быть две TLS-проверки: клиента с proxy и клиента с конечным сервером внутри туннеля. PROXY_SSL_* не заменяют SSL_* конечного адресата. В SOCKS4/5 разновидности различаются, в частности, местом DNS-разрешения имени.

HTTPS через HTTPS proxy
  1. PROXY задаёт посредника
  2. PROXY_SSL_* проверяют сертификат посредника
  3. CONNECT создаёт туннель к целевому host
  4. SSL_* проверяют уже целевой сервис
  5. HTTPAUTH и PROXYAUTH относятся к разным участникам
КонстантаНазначение, договор и границы
CURLOPT_HTTPPROXYTUNNEL
Тип самой константы: int

Включает CONNECT через заданный HTTP proxy к host:port. Proxy должен разрешать нужный port. Это отличается от обычной пересылки HTTP: без tunnel не-HTTP URL может быть отправлен proxy как HTTP GET. SUPPRESS_CONNECT_HEADERS скрывает proxy headers от callbacks; TLS origin всё равно проверяется отдельно.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.3.0. Native API: libcurl 7.3.

PHP: CURLOPT_HTTPPROXYTUNNEL; libcurl: CURLOPT_HTTPPROXYTUNNEL

CURLOPT_NOPROXY
Тип самой константы: int

Список domain/host через запятую, которым proxy не нужен; domain совпадает также с subdomains. Единственный wildcard — "*", отключающий proxy всем. "" явно разрешает proxy для всех, перекрывая env. IPv6 писать без скобок, IDN — punycode; CIDR для IP доступен с7.86. Это исключения маршрута proxy, не allowlist безопасных адресов.

Значение/результат: string|null.

По умолчанию: null: учитывать no_proxy/NO_PROXY.

Версии: Доступно с libcurl 7.19.4. Native API: libcurl 7.19.4.

PHP: CURLOPT_NOPROXY; libcurl: CURLOPT_NOPROXY

CURLOPT_PRE_PROXY
Тип самой константы: int

SOCKS proxy перед HTTP(S) proxy из PROXY. Схемы socks4/socks4a/socks5/socks5h задают версию и место DNS; без scheme defaultSOCKS4. IPv6 в [скобках], port лучше указать явно. "" выключает preproxy. Это цепочка из двух proxy, не запасной сервер на случай отказа.

Значение/результат: string|null.

По умолчанию: null; port по умолчанию1080.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PRE_PROXY; libcurl: CURLOPT_PRE_PROXY

CURLOPT_PROXY
Тип самой константы: int

Proxy hostname/IP/[IPv6] с явным scheme:// и :port. http default, https защищает proxy-слой; socks4a/socks5h переносят DNS на proxy, socks4/socks5 обычно разрешают локально. Без явного port native defaults зависят от схемы: лучше не угадывать. "" полностью выключает proxy, включая env; null убирает явную настройку. SOCKS Unix socket возможен через localhost/path. Обычный HTTP proxy преобразует не-HTTP URL в HTTP request, если не включён tunnel; active FTP с proxy не применяется. Credentials лучше PROXYUSERNAME/PROXYPASSWORD. Env http_proxy/ftp_proxy/... и all_proxy/no_proxy учитываются при отсутствии явных настроек.

Значение/результат: string|null.

По умолчанию: null: учитывать proxy environment.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_PROXY; libcurl: CURLOPT_PROXY

CURLOPT_PROXYAUTH
Тип самой константы: int

HTTP proxy-аутентификация отдельно от origin HTTPAUTH. Несколько bits разрешают согласование и могут добавить round-trip; credentials отдельно PROXYUSERPWD/USERNAME/PASSWORD. Современный native ссылается на поддерживаемые CURLAUTH методы, поэтому старое PHP «только BASIC и NTLM» не универсально. Собственный Proxy-Authorization может конфликтовать.

Значение/результат: int-маска CURLAUTH_*.

По умолчанию: BASIC.

Версии: Доступно с libcurl 7.10.7. Native API: libcurl 7.10.7.

PHP: CURLOPT_PROXYAUTH; libcurl: CURLOPT_PROXYAUTH

CURLOPT_PROXYHEADER
Тип самой константы: int

HTTP headers для proxy по тем же правилам HTTPHEADER: без CRLF, без request line, с контролем недоверенных values. Последний список заменяет прежний. Учитывать HEADEROPT: UNIFIED игнорирует этот список, SEPARATE отделяет CONNECT от origin headers.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с PHP 7.0.7 и libcurl 7.37.0. Native API: libcurl 7.37.0.

PHP: CURLOPT_PROXYHEADER; libcurl: CURLOPT_PROXYHEADER

CURLOPT_PROXYPASSWORD
Тип самой константы: int

Пароль входа на proxy вместе с PROXYUSERNAME. Не пароль origin и не passphrase proxy client TLS key. Отдельный параметр не требует конструировать URL с секретом.

Значение/результат: string|null.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1.

PHP: CURLOPT_PROXYPASSWORD; libcurl: CURLOPT_PROXYPASSWORD

CURLOPT_PROXYPORT
Тип самой константы: int

Отдельный proxy port, если не задан в строке PROXY. Native рекомендует явный port в proxy URL; текущие defaults443 дляhttps и1080 для остальных. 0 снимает override; эта настройка не выбирает port конечного сервера.

Значение/результат: int,0..65535.

По умолчанию: 0: URL/default.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_PROXYPORT; libcurl: CURLOPT_PROXYPORT

CURLOPT_PROXYTYPE
Тип самой константы: int

Выбор HTTP/HTTPS/HTTPS2/HTTP_1_0/SOCKS4/4A/5/5_HOSTNAME по соответствующей группе. Scheme PROXY часто яснее. HTTP_1_0 относится к CONNECT, не версии origin-запроса. Native новые виды, например experimentalHTTPS3, могут ещё не быть экспортированы PHP.

Значение/результат: int CURLPROXY_*.

По умолчанию: HTTP.

Версии: Доступно с libcurl 7.10. Native API: libcurl 7.10.

PHP: CURLOPT_PROXYTYPE; libcurl: CURLOPT_PROXYTYPE

CURLOPT_PROXYUSERNAME
Тип самой константы: int

Имя пользователя proxy-протокола. Пароль задаётся PROXYPASSWORD, допустимые методы — PROXYAUTH или SOCKS-настройки. Не переносится как username origin.

Значение/результат: string|null.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1.

PHP: CURLOPT_PROXYUSERNAME; libcurl: CURLOPT_PROXYUSERNAME

CURLOPT_PROXYUSERPWD
Тип самой константы: int

Строка username:password для HTTP proxy. В отличие от USERPWD, оба компонента native URL-decode: двоеточие внутри имени кодируется%3A. Проще отдельные PROXYUSERNAME/PROXYPASSWORD, чтобы не смешивать разделитель и данные. Метод задаёт PROXYAUTH.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_PROXYUSERPWD; libcurl: CURLOPT_PROXYUSERPWD

CURLOPT_PROXY_CAINFO
Тип самой константы: int

CA bundle для проверки HTTPS proxy, отдельно от CAINFO origin. Имеет смысл при PROXY_SSL_VERIFYPEER; null возвращает внутренний default. Совпадение содержимого двух CA stores не следует предполагать.

Значение/результат: string|null: PEM-файл.

По умолчанию: системный путь сборки.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_CAINFO; libcurl: CURLOPT_PROXY_CAINFO

CURLOPT_PROXY_CAINFO_BLOB
Тип самой константы: int

Содержимое доверенных CA из памяти для HTTPS proxy; имеет приоритет над PROXY_CAINFO. PHP constants ошибочно называет значение именем PEM-файла: native/PHP blob API принимает сами байты. Это не сертификат клиента и не CA origin.

Значение/результат: string: PEM-байты.

По умолчанию: не задан.

Версии: Доступно с PHP 8.2.0 и libcurl 7.77.0. Native API: libcurl 7.77.0.

PHP: CURLOPT_PROXY_CAINFO_BLOB; libcurl: CURLOPT_PROXY_CAINFO_BLOB

CURLOPT_PROXY_CAPATH
Тип самой константы: int

Каталог CA для HTTPS proxy при включённой проверке. OpenSSL требует подготовки c_rehash; backend/platform support проверяется отдельно. Не путать с каталогом приватных ключей клиента.

Значение/результат: string|null: каталог.

По умолчанию: native null/default backend.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_CAPATH; libcurl: CURLOPT_PROXY_CAPATH

CURLOPT_PROXY_CRLFILE
Тип самой константы: int

Список отзыва для проверки HTTPS proxy. OpenSSL проверяет CRL всей цепочки; GnuTLS имеет свои неизменяемые правила применения. Ошибка чтения списка — SSL_CRL_BADFILE, обнаруженный отзыв — ошибка верификации. Origin CRLFILE задаётся отдельно.

Значение/результат: string|null: PEM-файл CRL.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_CRLFILE; libcurl: CURLOPT_PROXY_CRLFILE

CURLOPT_PROXY_ISSUERCERT
Тип самой константы: int

Дополнительное ограничение issuer сертификата HTTPS proxy. Не добавляет доверие к issuer автоматически; PROXY_SSL_VERIFYPEER должна быть включена для отказа при несовпадении. Не равно CA bundle.

Значение/результат: string|null: PEM-файл.

По умолчанию: null.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_PROXY_ISSUERCERT; libcurl: CURLOPT_PROXY_ISSUERCERT

CURLOPT_PROXY_ISSUERCERT_BLOB
Тип самой константы: int

Та же проверка конкретного issuer HTTPS proxy из памяти. PHP передаёт строку, не C curl_blob. Требует PROXY_SSL_VERIFYPEER; сам issuer не становится проверенным доверенным корнем.

Значение/результат: string: PEM-байты.

По умолчанию: не задан.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_PROXY_ISSUERCERT_BLOB; libcurl: CURLOPT_PROXY_ISSUERCERT_BLOB

CURLOPT_PROXY_KEYPASSWD
Тип самой константы: int

Passphrase приватного ключа клиента PROXY_SSLKEY при входе на HTTPS proxy. Отличается от PROXYPASSWORD — пароля protocol auth, и от KEYPASSWD для origin.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_KEYPASSWD; libcurl: CURLOPT_PROXY_KEYPASSWD

CURLOPT_PROXY_PINNEDPUBLICKEY
Тип самой константы: int

Pin публичного ключа HTTPS proxy: PEM/DER файл либо один/несколько sha256//base64 через;. Несовпадение прерывает TLS с SSL_PINNEDPUBKEYNOTMATCH. Отдельно от PINNEDPUBLICKEY origin; планировать ротацию доверенных pins.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_PINNEDPUBLICKEY; libcurl: CURLOPT_PROXY_PINNEDPUBLICKEY

CURLOPT_PROXY_SERVICE_NAME
Тип самой константы: int

Имя сервиса для proxy-аутентификации. HTTP поддерживается nativeс7.43, SOCKS5с7.49. Это не hostname proxy и не service-account password.

Значение/результат: string|null.

По умолчанию: HTTP дляHTTP proxy;rcmd дляSOCKS5.

Версии: Доступно с PHP 7.0.7, libcurl 7.43.0 (for HTTP proxies) и libcurl 7.49.0 (for SOCKS5 proxies). Native API: libcurl 7.43.0.

PHP: CURLOPT_PROXY_SERVICE_NAME; libcurl: CURLOPT_PROXY_SERVICE_NAME

CURLOPT_PROXY_SSLCERT
Тип самой константы: int

Клиентский сертификат для HTTPS proxy, часто вместе с PROXY_SSLKEY. Текущий default форматаPEM; исторические NSS/SecureTransport сборки допускали nickname security database и требовали ./ для локального файла, SecureTransport использовал P12. Возможности старых backend не гарантированы текущей сборкой.

Значение/результат: string|null: файл клиентского сертификата.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSLCERT; libcurl: CURLOPT_PROXY_SSLCERT

CURLOPT_PROXY_SSLCERTTYPE
Тип самой константы: int

Формат proxy client certificate: PEM/DER согласно backend; OpenSSL/Schannel поддерживают P12. Старый PHP текст о SecureTransport/iOS относится к тем сборкам. Формат выбирается по реальным байтам файла, не по одному расширению имени.

Значение/результат: string.

По умолчанию: PEM.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSLCERTTYPE; libcurl: CURLOPT_PROXY_SSLCERTTYPE

CURLOPT_PROXY_SSLCERT_BLOB
Тип самой константы: int

Proxy client certificate из памяти вместо файла. Текущие native условия: Schannel P12, OpenSSL P12/PEM, Rustls PEM; формат явно PROXY_SSLCERTTYPE. Это клиентская идентичность, не доверенный CA proxy.

Значение/результат: string: байты сертификата.

По умолчанию: не задан.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_PROXY_SSLCERT_BLOB; libcurl: CURLOPT_PROXY_SSLCERT_BLOB

CURLOPT_PROXY_SSLKEY
Тип самой константы: int

Ключ клиента для HTTPS proxy, формат меняет PROXY_SSLKEYTYPE. Schannel игнорирует отдельный файл: ждёт ключ в keychain/P12 сертификата; исторический SecureTransport тоже имел такое ограничение. Права на файл ключа ограничиваются приложением.

Значение/результат: string|null: файл приватного ключа.

По умолчанию: null; форматPEM.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSLKEY; libcurl: CURLOPT_PROXY_SSLKEY

CURLOPT_PROXY_SSLKEYTYPE
Тип самой константы: int

Формат proxy private key: PEM,DER,ENG; PROV добавлен native8.12 для provider. Поддержка зависит от TLS backend, не все форматы работают в каждой сборке.

Значение/результат: string.

По умолчанию: PEM.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSLKEYTYPE; libcurl: CURLOPT_PROXY_SSLKEYTYPE

CURLOPT_PROXY_SSLKEY_BLOB
Тип самой константы: int

Приватный ключ клиента для HTTPS proxy из памяти. Native поддержка OpenSSL/Rustls, формат задаётся PROXY_SSLKEYTYPE. Строка содержит секрет; не печатать и не складывать в общий debug dump.

Значение/результат: string: байты ключа.

По умолчанию: не задан.

Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0.

PHP: CURLOPT_PROXY_SSLKEY_BLOB; libcurl: CURLOPT_PROXY_SSLKEY_BLOB

CURLOPT_PROXY_SSLVERSION
Тип самой константы: int

Диапазон TLS для соединения к HTTPS proxy, отдельно от SSLVERSION origin. Минимум и максимум задаются соответствующими flags; DEFAULT зависит от версии/backend. Старая proxy-страница native содержит ограничения прежних wolfSSL/MAX defaults; не переносить их как общую гарантию текущей сборки. Предпочитать актуальные безопасные defaults и тестируемую политику совместимости.

Значение/результат: int CURL_SSLVERSION_* с optionalMAX mask.

По умолчанию: DEFAULT.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSLVERSION; libcurl: CURLOPT_PROXY_SSLVERSION

CURLOPT_PROXY_SSL_CIPHER_LIST
Тип самой константы: int

Список TLS1.2/1.1/1.0 suites для HTTPS proxy через двоеточие. OpenSSL также допускает пробелы/запятые и операторы !,-,+; Schannel задаёт algorithms, не конкретные suites. TLS1.3 имеет отдельный PROXY_TLS13_CIPHERS. Не копировать названия suites между несовместимыми backend.

Значение/результат: string|null.

По умолчанию: список TLS backend.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSL_CIPHER_LIST; libcurl: CURLOPT_PROXY_SSL_CIPHER_LIST

CURLOPT_PROXY_SSL_OPTIONS
Тип самой константы: int

Специальные TLS-политики proxy: ALLOW_BEAST,NO_REVOKE,NO_PARTIALCHAIN,REVOKE_BEST_EFFORT,NATIVE_CA,AUTO_CLIENT_CERT. Область действия/версии/backend описаны у каждого бита. Некоторые снижают защиту или раскрывают клиентский сертификат; не добавлять «все bits» ради совместимости.

Значение/результат: int-маска CURLSSLOPT_*.

По умолчанию: 0.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSL_OPTIONS; libcurl: CURLOPT_PROXY_SSL_OPTIONS

CURLOPT_PROXY_SSL_VERIFYHOST
Тип самой константы: int

Проверка имени HTTPS proxy в SAN/CN сертификата. 0 отключает, не безопасное исправление ошибки. История общего VERIFYHOST:1 был debug до 7.28.0, ошибкой 7.28.1–7.65.3, эквивалентен 2 с 7.66; сама proxy-опция появилась лишь 7.52. Всегда явно 2, цепочку доверия проверяет отдельный PROXY_SSL_VERIFYPEER.

Значение/результат: int2|0.

По умолчанию: 2.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSL_VERIFYHOST; libcurl: CURLOPT_PROXY_SSL_VERIFYHOST

CURLOPT_PROXY_SSL_VERIFYPEER
Тип самой константы: int

Проверка подлинности цепочки HTTPS proxy через PROXY_CAINFO/PROXY_CAPATH. В PHP constants здесь ошибочно перечислены origin CAINFO/CAPATH; proxy имеет собственные настройки. Отключение пропускает недоверенный сертификат, а шифрование само не подтверждает правильного адресата. Имя отдельно PROXY_SSL_VERIFYHOST.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_SSL_VERIFYPEER; libcurl: CURLOPT_PROXY_SSL_VERIFYPEER

CURLOPT_PROXY_TLS13_CIPHERS
Тип самой константы: int

TLS1.3 suites proxy через двоеточие; для TLS<=1.2 — PROXY_SSL_CIPHER_LIST. Первоначальная поддержка была OpenSSL 1.1.1+, текущая применимость определяется backend и версией. Это не список сертификатов.

Значение/результат: string|null.

По умолчанию: список TLS backend.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0. Native API: libcurl 7.61.0.

PHP: CURLOPT_PROXY_TLS13_CIPHERS; libcurl: CURLOPT_PROXY_TLS13_CIPHERS

CURLOPT_PROXY_TLSAUTH_PASSWORD
Тип самой константы: int

Пароль TLS-SRP proxy вместе с PROXY_TLSAUTH_USERNAME/TYPE. Отличается от обычной HTTP proxy authentication. Native опция deprecated с libcurl8.22; сохраняется для понимания старого окружения.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_TLSAUTH_PASSWORD; libcurl: CURLOPT_PROXY_TLSAUTH_PASSWORD

CURLOPT_PROXY_TLSAUTH_TYPE
Тип самой константы: int

Специализированный метод TLS-аутентификации HTTPS proxy: "SRP" при shared secret, нужны USERNAME и PASSWORD семейства PROXY_TLSAUTH. Не обычный Basic/Bearer. Native deprecated с 8.22.

Значение/результат: string|null.

По умолчанию: не задан.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_TLSAUTH_TYPE; libcurl: CURLOPT_PROXY_TLSAUTH_TYPE

CURLOPT_PROXY_TLSAUTH_USERNAME
Тип самой константы: int

Имя TLS-SRP proxy-аутентификации вместе с PASSWORD/TYPE, не PROXYUSERNAME HTTP-аутентификации. Native deprecated с 8.22, наличие константы не означает поддержку backend.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Native API: libcurl 7.52.0.

PHP: CURLOPT_PROXY_TLSAUTH_USERNAME; libcurl: CURLOPT_PROXY_TLSAUTH_USERNAME

CURLOPT_SOCKS5_AUTH
Тип самой константы: int

Разрешает SOCKS5 username/password и/или GSSAPI; credentials — PROXYUSERPWD/USERNAME/PASSWORD. NONE=0 предлагает только no-auth; обычная маска также допускает no-auth, поэтому BASIC не означает «обязательно пароль». Текущий native позволяет ONLY вместе с BASIC/GSSAPI требовать auth, ONLY без метода — ошибка. Метод входа обычно не меняет connection security context; reuse может использовать ранее установленное соединение. Уточнять поддержку ONLY у развёрнутой версии, не переносить текущий контракт на старые libcurl.

Значение/результат: int-маска CURLAUTH_*.

По умолчанию: BASIC|GSSAPI.

Версии: Доступно с PHP 7.3.0 и libcurl 7.55.0. Native API: libcurl 7.55.0.

PHP: CURLOPT_SOCKS5_AUTH; libcurl: CURLOPT_SOCKS5_AUTH

CURLOPT_SOCKS5_GSSAPI_NEC
Тип самой константы: int

Разрешает незащищённое согласование protection mode для совместимости NEC, хотя RFC1961 требует защиты. Это узкое ослабление handshake, а не включение GSSAPI как такового; задавать только при известном контракте proxy.

Значение/результат: bool.

По умолчанию: native-страница не задаёт стабильный default.

Версии: Доступно с libcurl 7.19.4. Native API: libcurl 7.19.4.

PHP: CURLOPT_SOCKS5_GSSAPI_NEC; libcurl: CURLOPT_SOCKS5_GSSAPI_NEC

CURLOPT_SUPPRESS_CONNECT_HEADERS
Тип самой константы: int

Не передавать заголовки ответа proxy на CONNECT в HEADERFUNCTION/WRITEFUNCTION. Последующие заголовки целевого HTTP-ответа сохраняются. CURLINFO_HEADER_SIZE всё равно учитывает CONNECT-заголовки, поэтому это число нельзя использовать как смещение в уже отфильтрованном выводе.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.54.0. Native API: libcurl 7.54.0.

PHP: CURLOPT_SUPPRESS_CONNECT_HEADERS; libcurl: CURLOPT_SUPPRESS_CONNECT_HEADERS

CURLPROXY_HTTP
Тип самой константы: int

Обычный HTTP-прокси. Это тип связи с proxy, а не запрет HTTPS к конечному серверу.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.

PHP: CURLPROXY_HTTP; libcurl: CURLOPT_PROXYTYPE

CURLPROXY_HTTPS
Тип самой константы: int

HTTP-прокси, к которому само соединение защищено TLS. Проверки PROXY_SSL_* относятся к нему, SSL_* — к целевому серверу.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0

PHP: CURLPROXY_HTTPS; libcurl: CURLOPT_PROXYTYPE

CURLPROXY_HTTP_1_0
Тип самой константы: int

HTTP-прокси с HTTP/1.0 в CONNECT-запросе к туннелю. Это не принудительный HTTP/1.0 конечного сервера.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.19.3

PHP: CURLPROXY_HTTP_1_0; libcurl: CURLOPT_PROXYTYPE

CURLPROXY_SOCKS4
Тип самой константы: int

SOCKS4: имя конечного сервера разрешает локальная сторона; формат ограничен возможностями SOCKS4.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.

PHP: CURLPROXY_SOCKS4; libcurl: CURLOPT_PROXYTYPE

CURLPROXY_SOCKS4A
Тип самой константы: int

SOCKS4a передаёт hostname на разрешение прокси, в отличие от обычного SOCKS4.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPROXY_SOCKS4A; libcurl: CURLOPT_PROXYTYPE

CURLPROXY_SOCKS5
Тип самой константы: int

SOCKS5 с локальным разрешением hostname; аутентификация настраивается отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.

PHP: CURLPROXY_SOCKS5; libcurl: CURLOPT_PROXYTYPE

CURLPROXY_SOCKS5_HOSTNAME
Тип самой константы: int

SOCKS5 с разрешением hostname на стороне proxy. Это влияет на DNS-маршрут и политику доступа, не делает адрес автоматически безопасным.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPROXY_SOCKS5_HOSTNAME; libcurl: CURLOPT_PROXYTYPE

Cookie engine и cookie-файлы

Сохранение cookie — состояние клиента между передачами. COOKIEFILE читает исходные данные; COOKIEJAR задаёт сохранение. Ошибка записи jar может не стать ошибкой последнего HTTP-запроса, поэтому проверяйте права/жизненный цикл отдельно. Файл cookie — чувствительный файл, его нельзя размещать в публичном каталоге.

Cookie jar нужен клиенту, который сохраняет состояние между запросами одного сервиса. Это отдельное хранилище cURL, а не автоматически $_COOKIE посетителя вашего сайта. Сначала добавим искусственную несекретную cookie только в память и прочтём состояние без запроса.

Cookie только в памяти клиента
  1. COOKIELIST получает Netscape-строку cart=42
  2. Cookie engine сохраняет domain/path/flags
  3. CURLINFO_COOKIELIST возвращает список
  4. Команда ALL очищает его

Этот вариант. Поля разделены табуляцией: domain, include-subdomains, path, secure, expires, name, value. Ноль означает session cookie. Пример не отправлял cookie и не создавал jar-файл. В настоящем клиенте не печатайте session tokens; не разделяйте одно cookie-хранилище между независимыми пользователями.

Добавить и удалить учебную cookieСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
$cookie = "example.test\tFALSE\t/\tFALSE\t0\tcart\t42";
if (!curl_setopt($handle, CURLOPT_COOKIELIST, $cookie)) throw new RuntimeException('Cookie отклонена');
$saved = curl_getinfo($handle, CURLINFO_COOKIELIST);
if (!is_array($saved)) throw new RuntimeException('Нет списка');
echo 'Cookie в памяти: ', count($saved), "\n";
curl_setopt($handle, CURLOPT_COOKIELIST, 'ALL');
$cleared = curl_getinfo($handle, CURLINFO_COOKIELIST);
echo 'После очистки: ', is_array($cleared) ? count($cleared) : -1, "\n";
Ожидаемый результат
Cookie в памяти: 1
После очистки: 0
КонстантаНазначение, договор и границы
CURLOPT_COOKIE
Тип самой константы: int

Явная строка "name=value; other=value" для исходящего Cookie. Не проверяется как безопасный синтаксис и не включает cookie engine. Хранится отдельно от автоматически принятых cookies: одинаковые имена могут отправиться дважды. Последняя установка заменяет строку; null убирает. Для изменяемого cookie store нужен COOKIELIST. При redirect/повторном запросе учитывать передачу заголовка и правила origin.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_COOKIE; libcurl: CURLOPT_COOKIE

CURLOPT_COOKIEFILE
Тип самой константы: int

Читает Netscape/Mozilla cookie file или HTTP Set-Cookie строки и включает cookie engine. "" включает engine без файла; "-" читает stdin. Чтение происходит при начале передачи, не при setopt; несколько вызовов добавляют файлы. Несуществующие пути/каталоги игнорируются. null отключает engine и очищает список файлов. Set-Cookie без Domain небезопасно неоднозначен; предпочтителен Netscape формат. Для записи нужен COOKIEJAR.

Значение/результат: string|null: имя файла.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_COOKIEFILE; libcurl: CURLOPT_COOKIEFILE

CURLOPT_COOKIEJAR
Тип самой константы: int

Включает cookie engine и сохраняет внутренние cookies при уничтожении handle; файл сам не читается. "-" выводит cookies в stdout, что раскрывает секреты. В PHP8 curl_close не уничтожает объект: для ранней записи используйте COOKIELIST="FLUSH". Ошибка поздней записи может быть видна только в verbose/debug, поэтому наличие true у setopt не доказывает сохранение. Без cookies файл не создаётся; cookies Set-Cookie без domain не экспортируются. Каталог и права должны принадлежать приложению.

Значение/результат: string|null: имя файла.

По умолчанию: null.

Версии: Доступно с libcurl 7.9.0. Native API: libcurl 7.9.

PHP: CURLOPT_COOKIEJAR; libcurl: CURLOPT_COOKIEJAR

CURLOPT_COOKIELIST
Тип самой константы: int

Вставляет одну cookie-строку Netscape либо Set-Cookie и включает engine. Команды с точным регистром: ALL удалить всё из памяти; SESS удалить session cookies; FLUSH записать COOKIEJAR; RELOAD прочитать COOKIEFILE (учитывая COOKIESESSION). Вручную вставляемые cookies обходят автоматическую PSL-проверку — приложение проверяет domain. Set-Cookie без domain может отправляться разным узлам и не заменяться сервером; используйте Netscape формат с явным доменом.

Значение/результат: string.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.14.1. Native API: libcurl 7.14.1.

PHP: CURLOPT_COOKIELIST; libcurl: CURLOPT_COOKIELIST

CURLOPT_COOKIESESSION
Тип самой константы: int

Отмечает новую cookie-сессию: при последующей загрузке игнорировать старые cookies без даты истечения. Не удаляет автоматически всё уже находящееся в памяти и не завершает серверную авторизацию. Для очистки текущих session cookies есть COOKIELIST="SESS".

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.9.7. Native API: libcurl 7.9.7.

PHP: CURLOPT_COOKIESESSION; libcurl: CURLOPT_COOKIESESSION

Alt-Svc и HSTS

Alt-Svc разрешает использовать объявленную сервером альтернативную точку обслуживания, HSTS запоминает требование HTTPS. Они меняют будущие соединения, поэтому сведения принимаются только из доверенного контекста; отключение TLS-проверок может отравить такие кэши. READONLYFILE запрещает обратную запись, а не чтение.

Запомненная политика сервера
  1. Проверенный HTTPS сообщает HSTS/Alt-Svc
  2. Клиент сохраняет разрешённые сведения в памяти/файле
  3. Следующая передача применяет политику
  4. Доверенный каталог и проверка TLS сохраняют границы доверия
КонстантаНазначение, договор и границы
CURLALTSVC_H1
Тип самой константы: int

Бит разрешения альтернативного сервиса HTTP/1.1 из Alt-Svc. Alt-Svc принимается/используется с проверенным HTTPS, не из произвольного незашифрованного объявления.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1.

PHP: CURLALTSVC_H1; libcurl: CURLOPT_ALTSVC_CTRL

CURLALTSVC_H2
Тип самой константы: int

Бит альтернативного HTTP/2. Игнорируется, если сборка не поддерживает HTTP/2.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1.

PHP: CURLALTSVC_H2; libcurl: CURLOPT_ALTSVC_CTRL

CURLALTSVC_H3
Тип самой константы: int

Бит альтернативного HTTP/3. Игнорируется без поддержки HTTP/3; этот флаг не добавляет QUIC в сборку.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1.

PHP: CURLALTSVC_H3; libcurl: CURLOPT_ALTSVC_CTRL

CURLALTSVC_READONLYFILE
Тип самой константы: int

Не записывать изменённый Alt-Svc cache обратно в файл CURLOPT_ALTSVC. Чтение и in-memory изменения остаются отдельными действиями.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1.

PHP: CURLALTSVC_READONLYFILE; libcurl: CURLOPT_ALTSVC_CTRL

CURLHSTS_ENABLE
Тип самой константы: int

Включить in-memory HSTS cache handle: известные HSTS hosts переводятся с HTTP на HTTPS. Не обещает предварительный список всех защищённых сайтов.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0

PHP: CURLHSTS_ENABLE; libcurl: CURLOPT_HSTS_CTRL

CURLHSTS_READONLYFILE
Тип самой константы: int

Не сохранять изменённый HSTS cache в файл при освобождении handle; сам cache при этом может применяться в памяти.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0

PHP: CURLHSTS_READONLYFILE; libcurl: CURLOPT_HSTS_CTRL

CURLOPT_ALTSVC
Тип самой константы: int

Файл кеша Alt-Svc: прочитать существующие сведения и впоследствии сохранить обновления, если CTRL не содержит READONLYFILE. "" разрешает кеш без чтения из файла; null отключает этот путь. Последний путь заменяет прежний. Файл находится в доверенном каталоге с ограниченными правами: libcurl не защищает от другого пользователя, который может подменять файлы в том же каталоге.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1. Native API: libcurl 7.64.1.

PHP: CURLOPT_ALTSVC; libcurl: CURLOPT_ALTSVC

CURLOPT_ALTSVC_CTRL
Тип самой константы: int

Управляет альтернативными HTTP-сервисами. Любой установленный бит включает механизм; READONLYFILE запрещает обратную запись. Alt-Svc принимается по HTTPS, альтернативный origin тоже должен пройти HTTPS-проверку. Используется при новых соединениях: уже пригодное соединение из пула предпочтительнее. H2/H3 без поддержки сборкой не создают эту поддержку.

Значение/результат: int-маска CURLALTSVC_*.

По умолчанию: 0; при ALTSVC включаются поддерживаемые H1/H2/H3.

Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1. Native API: libcurl 7.64.1.

PHP: CURLOPT_ALTSVC_CTRL; libcurl: CURLOPT_ALTSVC_CTRL

CURLOPT_HSTS
Тип самой константы: int

Файл HSTS cache также включает HSTS. Несколько установок читают несколько файлов, но пишут в последний; null убирает файловый список и допускает memory-only HSTS. Нет файла/записей — пустой кеш. Формат строк: host и UTC срок "YYYYMMDD HH:MM:SS"; ведущая точка host включает subdomains, # — комментарий. С8.20 memory cache хранит до10000 последних hostnames. Права/каталог защищает приложение; предпочтительнее сразу использовать HTTPS, не надеясь на прежнюю запись HSTS.

Значение/результат: string|null.

По умолчанию: null: путь не задан.

Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0. Native API: libcurl 7.74.0.

PHP: CURLOPT_HSTS; libcurl: CURLOPT_HSTS

CURLOPT_HSTS_CTRL
Тип самой константы: int

ENABLE включает память HSTS: известные защищённые hosts автоматически переводятся с HTTP на HTTPS. READONLYFILE запрещает запись файла. Это не общий запрет всех HTTP URL, а кеш политики конкретных hosts.

Значение/результат: int-маска CURLHSTS_*.

По умолчанию: 0.

Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0. Native API: libcurl 7.74.0.

PHP: CURLOPT_HSTS_CTRL; libcurl: CURLOPT_HSTS_CTRL

Callback-функции, прогресс и пауза

Обработчик передают как callable, затем libcurl вызывает его в нужной фазе. Подписи и значения возврата у обработчиков различаются: длина принятой части, строка исходящих байтов, код продолжения/отказа. Пауза означает сохранение состояния передачи, а не sleep внутри callback; для возобновления передают полную маску состояния.

Ответ может прийти несколькими частями. Callback — функция, которую вызывает libcurl по мере поступления данных. У WRITEFUNCTION первый параметр — клиент, второй — очередная строка байтов. Возврат числа подтверждает, сколько байтов принято. Чтобы сначала понять механику без сети, читаем маленький приложенный файл через file://.

Получить складскую строку частями
  1. Файл содержит A42,7 и перевод строки
  2. WRITEFUNCTION получает очередной chunk
  3. Добавляет его к $received
  4. Возвращает strlen(chunk)
  5. После exec собрана исходная строка

Этот вариант. Файл stock.csv приложен; доступ к внешней сети не нужен. use (&$received) разрешает функции изменять внешнюю переменную, .= дописывает строку. Количество частей зависит от libcurl, поэтому результат не считает вызовы. Возврат 0 при превышении лимита сообщает отказ принять часть; после ошибки неполный результат использовать нельзя. Для большого файла пишите в поток, а не накапливайте всё в строке.

Собрать маленький ответ с лимитом памятиСамостоятельный пример
<?php
declare(strict_types=1);

$path = realpath(__DIR__ . '/stock.csv');
if ($path === false) throw new RuntimeException('Нет учебного файла');
$url = 'file:///' . str_replace(['\\', ' '], ['/', '%20'], ltrim($path, '/'));
$handle = curl_init($url);
if ($handle === false) throw new RuntimeException('Нет клиента');
$received = '';
$limit = 100;
curl_setopt($handle, CURLOPT_PROTOCOLS_STR, 'file');
curl_setopt($handle, CURLOPT_WRITEFUNCTION,
    function (CurlHandle $handle, string $chunk) use (&$received, $limit): int {
        $bytes = strlen($chunk);
        if ($bytes > $limit - strlen($received)) return 0;
        $received .= $chunk;
        return $bytes;
    });
if (curl_exec($handle) === false) throw new RuntimeException(curl_error($handle));
echo "Получено: ", trim($received), "\n";
Ожидаемый результат
Получено: A42,7

Этот вариант. Возврат 0 вместо длины непустой части — осознанный отказ получателя. Это локальная ошибка записи, а не HTTP 500 от сервера. В рабочем коде сохраняйте собственную причину остановки: одного CURLE_WRITE_ERROR недостаточно, чтобы отличить лимит размера от отказа диска.

Распознать остановку из-за лимита получателяСамостоятельный пример
<?php
declare(strict_types=1);

$path = realpath(__DIR__ . '/stock.csv');
if ($path === false) throw new RuntimeException('Нет файла');
$url = 'file:///' . str_replace(['\\', ' '], ['/', '%20'], ltrim($path, '/'));
$handle = curl_init($url);
if ($handle === false) throw new RuntimeException('Нет клиента');
curl_setopt($handle, CURLOPT_WRITEFUNCTION,
    static function (CurlHandle $handle, string $chunk): int { return 0; });
$result = curl_exec($handle);
echo $result === false && curl_errno($handle) === CURLE_WRITE_ERROR
    ? "Получатель остановил передачу\n" : "Неожиданный результат\n";
Ожидаемый результат
Получатель остановил передачу

Важные различия: HEADERFUNCTION получает строки заголовков, включая промежуточные ответы; READFUNCTION отдаёт исходящие байты, а пустая строка означает конец ввода; progress callback сообщает счётчики и может отменить передачу. Не разбирайте каждую часть WRITEFUNCTION как самостоятельный JSON и не декодируйте UTF-8 по произвольным границам. Не вызывайте из callback повторный curl_exec/reset того же активного handle.

КонстантаНазначение, договор и границы
CURLOPT_FNMATCH_FUNCTION
Тип самой константы: int

PHP8 callback(CurlHandle $handle,string $pattern,string $name):int сопоставляет wildcard и имя. Возвращает MATCH, NOMATCH либо FAIL из CURL_FNMATCHFUNC_*. ДоPHP8 первый аргумент был resource. Применяется к WILDCARDMATCH; false/true вместо enum скрывают различие ошибки и совпадения.

Значение/результат: callable|null.

По умолчанию: внутренний matcher.

Версии: Доступно с libcurl 7.21.0. Native API: libcurl 7.21.0.

PHP: CURLOPT_FNMATCH_FUNCTION; libcurl: CURLOPT_FNMATCH_FUNCTION

CURLOPT_HEADERFUNCTION
Тип самой константы: int

PHP8 callback(CurlHandle $handle,string $line):int получает полные header lines с конечным переводом строки. Вернуть strlen($line); другое число прерывает передачу WRITE_ERROR. Приходят status line, пустая разделительная строка, промежуточные ответы/redirect/auth и trailers; приложение разграничивает блоки. Строка может быть до100KiB. Сlibcurl8.18 folded HTTP/1 headers разворачиваются в одну строку. Не-HTTP протоколы передают ответы на команды. ДоPHP8 handle был resource.

Значение/результат: callable|null.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.7.2. Native API: libcurl 7.7.2.

PHP: CURLOPT_HEADERFUNCTION; libcurl: CURLOPT_HEADERFUNCTION

CURLOPT_NOPROGRESS
Тип самой константы: int

Полностью выключает progress meter и вызовы PROGRESSFUNCTION/XFERINFOFUNCTION. Для собственного progress/отмены нужно false; это полезно не только для отладки. Без callback не включайте лишний вывод в HTTP-ответ приложения.

Значение/результат: bool.

По умолчанию: true в PHP.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_NOPROGRESS; libcurl: CURLOPT_NOPROGRESS

CURLOPT_PREREQFUNCTION
Тип самой константы: int

После установки/выбора соединения и TLS, перед данными вызывается callback(handle, remoteIp, localIp, remotePort, localPort). Вернуть CURL_PREREQFUNC_OK либо ABORT; PHP отвергает неправильный тип/значение. IPv6 передаётся без квадратных скобок. При redirect вызовов может быть несколько; FTP относится к control channel. Не предотвращает само подключение к адресу и потому не заменяет политику SSRF до соединения. PHP 8.4/libcurl 7.80+.

Значение/результат: callable(CurlHandle, string, string, int, int): int.

По умолчанию: callback не установлен.

Версии: Доступно с PHP 8.4.0 и libcurl 7.80.0. Native API: libcurl 7.80.0.

PHP: CURLOPT_PREREQFUNCTION; libcurl: CURLOPT_PREREQFUNCTION

CURLOPT_PROGRESSFUNCTION
Тип самой константы: int

PHP callback(CurlHandle $h,int $downloadTotal,int $downloadNow,int $uploadTotal,int $uploadNow):int. Нужен NOPROGRESS=false. Нули могут означать неизвестный размер, поэтому не делить на total без проверки. 0 продолжает, ненулевой результат отменяет с ABORTED_BY_CALLBACK. В idle вызовы реже, в multi требуют выполнения движка. Native старый API использует double, PHP преобразует к int; с7.32 предпочтителен XFERINFOFUNCTION. В PHP нельзя полагаться на native специальный CONTINUE-code: wrapper считает любой nonzero отменой.

Значение/результат: callable|null.

По умолчанию: не задан, NOPROGRESS=true.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.32.0. Native API: libcurl 7.1.

PHP: CURLOPT_PROGRESSFUNCTION; libcurl: CURLOPT_PROGRESSFUNCTION

CURLOPT_READFUNCTION
Тип самой константы: int

PHP 8 callback(CurlHandle $h,$stream,int $maxBytes):string|int. Вернуть не более maxBytes байтов; "" означает EOF, CURL_READFUNC_PAUSE — временную паузу, не конец. $stream — resource либо null. PHP 8.5 обрезает слишком длинную строку до буфера, остаток автоматически не сохраняет: callback должен сам вести offset. Ранний EOF при обещанном большем размере может заставить сервер ждать. Повтор/redirect может потребовать rewind источника; TFTP считает неполный блок последним. Возвращать обычное число вместо bytes нельзя, кроме документированного специального pause-кода.

Значение/результат: callable|null.

По умолчанию: внутреннее чтение READDATA.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_READFUNCTION; libcurl: CURLOPT_READFUNCTION

CURLOPT_SSH_HOSTKEYFUNCTION
Тип самой константы: int

PHP 8 callback(CurlHandle $h,int $keyType,string $key,int $keyLength):int проверяет байты hostkey, тип native CURLKHTYPE_*. Вернуть строго CURLKHMATCH_OK либо MISMATCH; PHP 8.5 иначе Error. Переопределяет KNOWNHOSTS. Вызывается для новых соединений: ранее проверенное соединение может reuse без нового вызова даже после смены callback. Не принимать всё ради устранения ошибки.

Значение/результат: callable|null.

По умолчанию: не задан.

Версии: Доступно с PHP 8.3.0 и libcurl 7.84.0. Native API: libcurl 7.84.0.

PHP: CURLOPT_SSH_HOSTKEYFUNCTION; libcurl: CURLOPT_SSH_HOSTKEYFUNCTION

CURLOPT_WRITEFUNCTION
Тип самой константы: int

Получать тело частями. Возвращайте точное strlen принятой части, а не число символов Unicode; меньший результат останавливает передачу с CURLE_WRITE_ERROR. Callback может получить пустую строку, много маленьких или больших частей: границы JSON/строк/символов не сохраняются. CURL_WRITEFUNC_PAUSE приостанавливает, и данные могут поступить повторно после возобновления. Если смешать HEADER с телом, сюда попадут также заголовки. Обычно тело ограничивается native CURL_MAX_WRITE_SIZE, но код не должен требовать фиксированный размер.

Значение/результат: callable(CurlHandle, string): int.

По умолчанию: обычный вывод PHP / RETURNTRANSFER / FILE.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_WRITEFUNCTION; libcurl: CURLOPT_WRITEFUNCTION

CURLOPT_WRITEHEADER
Тип самой константы: int

Поток для заголовков; это PHP-имя native HEADERDATA. Не путь-строка. Сохраняйте поток открытым до завершения; для управляемого разбора строк ответа применяйте HEADERFUNCTION. Несколько HTTP-ответов (100, redirect, proxy CONNECT) дают несколько блоков заголовков.

Значение/результат: resource: открытый поток для записи.

По умолчанию: заголовки не сохраняются в отдельный поток.

Версии: Доступно с libcurl 7.1.0. Native API CURLOPT_HEADERDATA: libcurl 7.10.

PHP: CURLOPT_WRITEHEADER; libcurl: CURLOPT_HEADERDATA

CURLOPT_XFERINFOFUNCTION
Тип самой константы: int

Современный progress callback: handle, download total/current, upload total/current. Неизвестные totals равны 0; включается при NOPROGRESS=false. Возврат 0 продолжает, ненулевой — прерывает с CURLE_ABORTED_BY_CALLBACK. Частота не гарантируется, в multi она зависит от продвижения event loop. PHP экспортирует с 8.2; переданные счётчики ограничены PHP int. Это не событие завершения запроса.

Значение/результат: callable(CurlHandle, int, int, int, int): int.

По умолчанию: callback не установлен.

Версии: Доступно с PHP 8.2.0 и libcurl 7.32.0. Native API: libcurl 7.32.0.

PHP: CURLOPT_XFERINFOFUNCTION; libcurl: CURLOPT_XFERINFOFUNCTION

CURLPAUSE_ALL
Тип самой константы: int

Маска SEND | RECV: приостановить оба направления передачи.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPAUSE_ALL; libcurl: curl_easy_pause

CURLPAUSE_CONT
Тип самой константы: int

0: снять паузу обоих направлений. curl_pause принимает новое полное состояние, а не отдельную команду-переключатель.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPAUSE_CONT; libcurl: curl_easy_pause

CURLPAUSE_RECV
Тип самой константы: int

Маска приостанавливает получение. Если отправку тоже нужно оставить приостановленной, включите SEND через |.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPAUSE_RECV; libcurl: curl_easy_pause

CURLPAUSE_RECV_CONT
Тип самой константы: int

Историческое именованное значение 0. Хотя имя говорит о получении, передача его одного в curl_pause снимает обе паузы; для состояния «отправка на паузе, чтение активно» передайте SEND.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPAUSE_RECV_CONT; libcurl: curl_easy_pause

CURLPAUSE_SEND
Тип самой константы: int

Маска приостанавливает отправку. Чтобы одновременно оставить паузу чтения, включите RECV через |.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPAUSE_SEND; libcurl: curl_easy_pause

CURLPAUSE_SEND_CONT
Тип самой константы: int

Историческое именованное значение 0. Передача его одного снимает обе паузы; для состояния «чтение на паузе, отправка активна» передайте RECV.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURLPAUSE_SEND_CONT; libcurl: curl_easy_pause

CURL_FNMATCHFUNC_FAIL
Тип самой константы: int

Wildcard callback сообщает об ошибке сравнения; это не обычное несовпадение.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURL_FNMATCHFUNC_FAIL; libcurl: CURLOPT_FNMATCH_FUNCTION

CURL_FNMATCHFUNC_MATCH
Тип самой константы: int

Wildcard callback подтверждает совпадение имени с шаблоном: элемент можно обрабатывать.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURL_FNMATCHFUNC_MATCH; libcurl: CURLOPT_FNMATCH_FUNCTION

CURL_FNMATCHFUNC_NOMATCH
Тип самой константы: int

Wildcard callback сообщает отсутствие совпадения: этот элемент пропускается.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.21.0.

PHP: CURL_FNMATCHFUNC_NOMATCH; libcurl: CURLOPT_FNMATCH_FUNCTION

CURL_MAX_READ_SIZE
Тип самой константы: int

Верхняя граница буфера чтения libcurl, используемая, в частности, для UPLOAD_BUFFERSIZE. Это не размер файла, не число Unicode-символов и не обещание размера каждого callback chunk.

Значение/результат: int: предел размера в байтах.

Версии: Доступно с PHP 7.3.0 и libcurl 7.53.0

PHP: CURL_MAX_READ_SIZE; libcurl: CURLOPT_READFUNCTION

CURL_PREREQFUNC_ABORT
Тип самой константы: int

Ответ prereq callback: отменить передачу с CURLE_ABORTED_BY_CALLBACK до отправки запроса по уже подготовленному соединению.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.4.0 и libcurl 7.80.0.

PHP: CURL_PREREQFUNC_ABORT; libcurl: CURLOPT_PREREQFUNCTION

CURL_PREREQFUNC_OK
Тип самой константы: int

Ответ prereq callback: продолжить после установления/выбора соединения и handshake, но до отправки запроса. Не означает, что соединения до этого момента не было.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.4.0 и libcurl 7.80.0.

PHP: CURL_PREREQFUNC_OK; libcurl: CURLOPT_PREREQFUNCTION

CURL_READFUNC_PAUSE
Тип самой константы: int

Особый ответ read callback: сейчас нет данных, приостановить чтение из источника. Пустая строка означала бы EOF; возобновление организует приложение через curl_pause.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURL_READFUNC_PAUSE; libcurl: CURLOPT_READFUNCTION

CURL_WRITEFUNC_PAUSE
Тип самой константы: int

Особый ответ write callback: временно приостановить получение. При возобновлении libcurl может заново доставить удержанный chunk; не записывать его дважды. Обычно callback возвращает strlen($chunk), то есть число принятых байтов.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.18.0.

PHP: CURL_WRITEFUNC_PAUSE; libcurl: CURLOPT_WRITEFUNCTION

Получение, отправка и файловые потоки

Путь-строка, открытый stream resource и callback не взаимозаменяемы. INFILE предоставляет источник, FILE — приёмник, INFILESIZE описывает исходящий размер. Буфер — рабочая порция памяти; он не ограничивает весь ответ. MAXFILESIZE и прикладной лимит получателя решают задачу суммарного объёма.

Для больших ответов удобнее сразу писать в поток. Ресурс fopen — открытый канал записи, а не имя файла. Следующий опыт использует php://temp, чтобы не перезаписывать пользовательские файлы; отдельный приложенный stock.csv служит источником.

Передача в поток
  1. stock.csv → file:// URL
  2. FILE получает открытый $destination
  3. curl_exec пишет байты
  4. rewind возвращает позицию в начало
  5. stream_get_contents читает сохранённый текст

Этот вариант. w+b открывает бинарный поток для записи и чтения; rewind перемещает указатель. finally закрывает его после обычного завершения или исключения. FILE, RETURNTRANSFER и WRITEFUNCTION выбирают способы получения тела и взаимодействуют по порядку установки; не смешивайте их без конкретной причины.

Принять данные в управляемый потокСамостоятельный пример
<?php
declare(strict_types=1);

$path = realpath(__DIR__ . '/stock.csv');
if ($path === false) throw new RuntimeException('Нет файла');
$url = 'file:///' . str_replace(['\\', ' '], ['/', '%20'], ltrim($path, '/'));
$destination = fopen('php://temp', 'w+b');
if ($destination === false) throw new RuntimeException('Нет потока');
try {
    $handle = curl_init($url);
    if ($handle === false) throw new RuntimeException('Нет клиента');
    if (!curl_setopt($handle, CURLOPT_FILE, $destination)) throw new RuntimeException('Нет приёмника');
    if (curl_exec($handle) === false) throw new RuntimeException(curl_error($handle));
    rewind($destination);
    echo stream_get_contents($destination);
} finally {
    fclose($destination);
}
Ожидаемый результат
A42,7
КонстантаНазначение, договор и границы
CURLOPT_BUFFERSIZE
Тип самой константы: int

Желаемый receive buffer, не гарантия размера каждого write callback. Минимум1024, максимум CURL_MAX_READ_SIZE=10MiB в актуальном libcurl; до7.88 максимум512KiB. Не менять во время активной передачи. С8.7 multi использует общий transfer buffer для easy handles, пока есть активные передачи. Буфер не ограничивает суммарный размер ответа.

Значение/результат: int, байты.

По умолчанию: 16384 (CURL_MAX_WRITE_SIZE).

Версии: Доступно с libcurl 7.10. Native API: libcurl 7.10.

PHP: CURLOPT_BUFFERSIZE; libcurl: CURLOPT_BUFFERSIZE

CURLOPT_CRLF
Тип самой константы: int

Исторически заменяет Unix LF на CRLF при передаче. Меняет байты, поэтому не годится для двоичных payload, подписей или файлов, где нужна точная сохранность. Не является общей перекодировкой текста.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_CRLF; libcurl: CURLOPT_CRLF

CURLOPT_FILE
Тип самой константы: int

Куда записывать получаемый body. PHP адаптирует stream самостоятельно: C-предупреждение о Windows FILE* здесь не означает, что надо передавать native указатель. Держать поток открытым до завершения. Это alias WRITEDATA; взаимодействие с RETURNTRANSFER/WRITEFUNCTION зависит от выбранного PHP write handler и порядка настройки.

Значение/результат: resource: открытый writable PHP stream.

По умолчанию: обычный вывод PHP.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.9.7. Native API CURLOPT_WRITEDATA: libcurl 7.9.7.

PHP: CURLOPT_FILE; libcurl: CURLOPT_WRITEDATA

CURLOPT_FILETIME
Тип самой константы: int

Попросить дату изменения удалённого ресурса. Сервер/протокол может не предоставить её; CURLINFO_FILETIME/FILETIME_T тогда возвращают-1. Это не установка даты локального файла.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.5.0. Native API: libcurl 7.5.

PHP: CURLOPT_FILETIME; libcurl: CURLOPT_FILETIME

CURLOPT_IGNORE_CONTENT_LENGTH
Тип самой константы: int

Не полагаться на HTTP Content-Length/FTP size. Для старого сервера с неверным размером или растущего FTP-файла может быть необходимо; ухудшает точный progress, загрузка ориентируется на окончание потока. Это не защита от слишком большого ответа; собственный предел остаётся нужен.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.14.1. Native API: libcurl 7.14.1.

PHP: CURLOPT_IGNORE_CONTENT_LENGTH; libcurl: CURLOPT_IGNORE_CONTENT_LENGTH

CURLOPT_INFILE
Тип самой константы: int

Исторический alias READDATA: поток для upload. Держать открытым до завершения; READFUNCTION может заменить чтение. PHP работает с ресурсом fopen, не native FILE*. Native-имя deprecated с7.9.7; новый код READDATA.

Значение/результат: resource: readable PHP stream.

По умолчанию: стандартный PHP источник чтения.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.9.7. Native API CURLOPT_READDATA: libcurl 7.9.7.

PHP: CURLOPT_INFILE; libcurl: CURLOPT_READDATA

CURLOPT_INFILESIZE
Тип самой константы: int

Ожидаемый размер upload; для SCP обязателен этот или LARGE. -1 сбрасывает, HTTP1.1 upload неизвестного размера использует chunked. SMTP может использовать значение для SIZE при MAIL FROM. Это не ограничитель read callback: количество выдаваемых байтов должно соответствовать обещанию. Для >2GiB нужен INFILESIZE_LARGE и64-bit PHP.

Значение/результат: int, байты.

По умолчанию: -1: неизвестно.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_INFILESIZE; libcurl: CURLOPT_INFILESIZE

CURLOPT_INFILESIZE_LARGE
Тип самой константы: int

Вариант ожидаемого upload size через native curl_off_t; PHP-константа с8.5. Поддерживает >2GiB при представимом PHP int. Для SCP размер обязателен, SMTP использует optional SIZE. Не обрезает источник автоматически: READFUNCTION отвечает за фактически отданные байты; -1 убирает известный размер.

Значение/результат: int, байты.

По умолчанию: -1: неизвестно.

Версии: Доступно с PHP 8.5.0. Native API: libcurl 7.11.0.

PHP: CURLOPT_INFILESIZE_LARGE; libcurl: CURLOPT_INFILESIZE_LARGE

CURLOPT_MAXFILESIZE
Тип самой константы: int

Предел скачиваемого размера: известный слишком большой файл отвергается до передачи, сlibcurl8.4 лимит также останавливает растущую передачу. С8.20 учитываются и распакованные bytes ACCEPT_ENCODING. Отрицательное значение — BAD_FUNCTION_ARGUMENT; для >2GiB используйте LARGE. Старое утверждение «неизвестный размер не ограничивается» относится к ранним версиям; callback-limit полезен для переносимости.

Значение/результат: int, байты.

По умолчанию: 0: выключено.

Версии: Доступно с libcurl 7.10.8. Native API: libcurl 7.10.8.

PHP: CURLOPT_MAXFILESIZE; libcurl: CURLOPT_MAXFILESIZE

CURLOPT_MAXFILESIZE_LARGE
Тип самой константы: int

Тот же предел с расширенным native диапазоном. До8.4 неизвестный заранее размер не ограничивался; с8.4 передача останавливается по фактическому размеру, с8.20 также по распакованному объёму. Отрицательный лимит непригоден. PHP int должен представлять заданное число; старую фразу PHP constants об отсутствии эффекта для неизвестного размера нельзя переносить на текущую библиотеку.

Значение/результат: int, байты через native curl_off_t.

По умолчанию: 0: выключено.

Версии: Доступно с PHP 8.2.0 и libcurl 7.11.0. Native API: libcurl 7.11.0.

PHP: CURLOPT_MAXFILESIZE_LARGE; libcurl: CURLOPT_MAXFILESIZE_LARGE

CURLOPT_MAX_RECV_SPEED_LARGE
Тип самой константы: int

Приостанавливает download, чтобы средняя скорость удерживалась ниже лимита; не точный мгновенный регулятор. Начальный receive buffer может превысить маленький лимит. Не действует для file://. Это верхний speed cap, не LOW_SPEED_LIMIT.

Значение/результат: int, байты/секунду.

По умолчанию: 0: без ограничения.

Версии: Доступно с libcurl 7.15.5. Native API: libcurl 7.15.5.

PHP: CURLOPT_MAX_RECV_SPEED_LARGE; libcurl: CURLOPT_MAX_RECV_SPEED_LARGE

CURLOPT_MAX_SEND_SPEED_LARGE
Тип самой константы: int

Ограничивает среднюю скорость upload паузами. Первый upload buffer может временно превысить малое значение. Не действует для file://, не гарантирует время завершения и не заменяет общий timeout.

Значение/результат: int, байты/секунду.

По умолчанию: 0: без ограничения.

Версии: Доступно с libcurl 7.15.5. Native API: libcurl 7.15.5.

PHP: CURLOPT_MAX_SEND_SPEED_LARGE; libcurl: CURLOPT_MAX_SEND_SPEED_LARGE

CURLOPT_NEW_DIRECTORY_PERMS
Тип самой константы: int

Права создаваемых каталогов для SFTP/SCP/file. В PHP литерал0755 — восьмеричный; decimal755 означает другой набор bits. Сервер/ОС/umask могут дополнительно ограничить права. Настройка не меняет уже существующие каталоги.

Значение/результат: int: восьмеричные POSIX permission bits.

По умолчанию: 0755.

Версии: Доступно с libcurl 7.16.4. Native API: libcurl 7.16.4.

PHP: CURLOPT_NEW_DIRECTORY_PERMS; libcurl: CURLOPT_NEW_DIRECTORY_PERMS

CURLOPT_NEW_FILE_PERMS
Тип самой константы: int

Права новых файлов SFTP/SCP/file. Не вводить строку"644" как эквивалент восьмеричного0644 без преобразования. Реальная система прав/umask определяется платформой; это не универсальный Windows ACL редактор.

Значение/результат: int: восьмеричные POSIX permission bits.

По умолчанию: 0644.

Версии: Доступно с libcurl 7.16.4. Native API: libcurl 7.16.4.

PHP: CURLOPT_NEW_FILE_PERMS; libcurl: CURLOPT_NEW_FILE_PERMS

CURLOPT_RANGE
Тип самой константы: int

Диапазон байтов X-Y, X- либо -Y. HTTP допускает несколько через запятую; ответ тогда multipart и libcurl отдаёт его с metadata как есть — приложение разбирает. Сервер вправе проигнорировать Range и вернуть весь body: проверить status/Content-Range. Для RTSP вместо bytes используются npt/utc/smpte; для HTTP PUT uploads опция конфликтует с другими механизмами и не рекомендуется. null снимает.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_RANGE; libcurl: CURLOPT_RANGE

CURLOPT_READDATA
Тип самой константы: int

Поток fopen для чтения upload; PHP адаптирует его, не требует native FILE*. Передаётся вторым аргументом READFUNCTION, если callback установлен; без заданного stream callback получает null. Поток держать открытым. Без источника PHP direct-reader не обязан читать stdin как native C default.

Значение/результат: resource: readable PHP stream.

По умолчанию: источник не задан.

Версии: Доступно с libcurl 7.9.7. Native API: libcurl 7.9.7.

PHP: CURLOPT_READDATA; libcurl: CURLOPT_READDATA

CURLOPT_RESUME_FROM
Тип самой константы: int

Смещение возобновления; FTP -1 продолжает с конца target, FTP upload читает источник с resume offset и дописывает target. HTTP POST/PUT upload этим не возобновляются: nonzero даёт BAD_FUNCTION_ARGUMENT. Для native offset>2GiB существует RESUME_FROM_LARGE, но не всякое native имя экспортировано PHP. Проверять, что локальный и удалённый файлы соответствуют друг другу.

Значение/результат: int, байты.

По умолчанию: 0: сначала.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_RESUME_FROM; libcurl: CURLOPT_RESUME_FROM

CURLOPT_SAFE_UPLOAD
Тип самой константы: int

Отключает старую магию @filename в POSTFIELDS: строка, начинающаяся@, остаётся полем. Файлы отправляются CURLFile/CURLStringFile. Попытка false в PHP 8.5 выбрасывает ValueError; вернуть старый небезопасный режим нельзя. Это не проверка содержимого/размера самого файла.

Значение/результат: true.

По умолчанию: всегда true в текущем PHP.

PHP: CURLOPT_SAFE_UPLOAD

CURLOPT_UPLOAD
Тип самой константы: int

Готовить загрузку данных в ресурс; для HTTP без другого выбора это PUT. Байты берутся из INFILE/READFUNCTION, размер при наличии задаётся INFILESIZE. Для HTTP/1.1 неизвестный размер может вызвать chunked transfer, для HTTP/1.0 размер нужен. Это не multipart/form-data: его создаёт POSTFIELDS с полями/файлами.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_UPLOAD; libcurl: CURLOPT_UPLOAD

CURLOPT_UPLOAD_BUFFERSIZE
Тип самой константы: int

Запрашиваемый размер внутреннего upload-буфера: минимум 16384, максимум 2097152. Это пожелание, а не обещание размера каждого callback. Буфер выделяется при необходимости; не менять опцию во время активной передачи. Большой буфер увеличивает память при многих параллельных запросах.

Значение/результат: int: байты.

По умолчанию: 65536.

Версии: Доступно с PHP 8.2.0 и libcurl 7.62.0. Native API: libcurl 7.62.0.

PHP: CURLOPT_UPLOAD_BUFFERSIZE; libcurl: CURLOPT_UPLOAD_BUFFERSIZE

FTP/FTPS: данные и управляющее соединение

FTP использует управляющее соединение для команд и отдельный канал данных. В passive FTP к данным подключается клиент, в active FTP сервер соединяется обратно. FTPS добавляет TLS к FTP, а SFTP — другой протокол поверх SSH. Команды QUOTE/POSTQUOTE и APPEND имеют реальные побочные эффекты; повторять их вслепую нельзя.

Файл через passive FTPS
  1. Клиент соединяется с управляющим FTP endpoint
  2. USE_SSL=ALL требует TLS для команд и данных
  3. Сервер сообщает адрес/порт канала данных
  4. Клиент открывает канал и передаёт файл
  5. Приложение отдельно решает замену, append и безопасный повтор
КонстантаНазначение, договор и границы
CURLFTPAUTH_DEFAULT
Тип самой константы: int

Оставить libcurl выбор порядка AUTH SSL / AUTH TLS для FTPS.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPAUTH_DEFAULT; libcurl: CURLOPT_FTPSSLAUTH

CURLFTPAUTH_SSL
Тип самой константы: int

Сначала AUTH SSL, после отказа AUTH TLS. Это названия FTP-команд, не разрешение использовать небезопасный SSLv3.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPAUTH_SSL; libcurl: CURLOPT_FTPSSLAUTH

CURLFTPAUTH_TLS
Тип самой константы: int

Сначала AUTH TLS, после отказа AUTH SSL; имеет смысл при включённом USE_SSL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPAUTH_TLS; libcurl: CURLOPT_FTPSSLAUTH

CURLFTPMETHOD_DEFAULT
Тип самой константы: int

Стандартный способ обхода FTP-пути (MULTICWD).

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.15.3.

PHP: CURLFTPMETHOD_DEFAULT; libcurl: CURLOPT_FTP_FILEMETHOD

CURLFTPMETHOD_MULTICWD
Тип самой константы: int

Отдельная команда CWD для каждого компонента каталога в URL; затем работа с именем файла.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.15.3.

PHP: CURLFTPMETHOD_MULTICWD; libcurl: CURLOPT_FTP_FILEMETHOD

CURLFTPMETHOD_NOCWD
Тип самой константы: int

Не менять текущий каталог; передавать полный путь в SIZE/RETR/STOR и другие файловые команды.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.15.3.

PHP: CURLFTPMETHOD_NOCWD; libcurl: CURLOPT_FTP_FILEMETHOD

CURLFTPMETHOD_SINGLECWD
Тип самой константы: int

Один CWD с полным каталогом, затем операции с файлом. Уменьшает число CWD, но совместимость зависит от FTP-сервера.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.15.3.

PHP: CURLFTPMETHOD_SINGLECWD; libcurl: CURLOPT_FTP_FILEMETHOD

CURLFTPSSL_ALL
Тип самой константы: int

Требовать TLS и для управления, и для данных, иначе отказ. Для чтения ошибки libcurl использует USE_SSL_FAILED; не путать с простым наличием HTTPS в URL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPSSL_ALL; libcurl: CURLOPT_USE_SSL

CURLFTPSSL_CCC_ACTIVE
Тип самой константы: int

Инициировать завершение TLS на управляющем канале и дождаться ответа.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.16.2.

PHP: CURLFTPSSL_CCC_ACTIVE; libcurl: CURLOPT_FTP_SSL_CCC

CURLFTPSSL_CCC_NONE
Тип самой константы: int

Не выполнять Clear Command Channel: сохранить защищённый управляющий канал.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.16.2.

PHP: CURLFTPSSL_CCC_NONE; libcurl: CURLOPT_FTP_SSL_CCC

CURLFTPSSL_CCC_PASSIVE
Тип самой константы: int

Дождаться инициативы сервера завершить TLS, не инициировать и не отвечать тем же шагом. CCC сознательно делает управление незашифрованным.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.16.1.

PHP: CURLFTPSSL_CCC_PASSIVE; libcurl: CURLOPT_FTP_SSL_CCC

CURLFTPSSL_CONTROL
Тип самой константы: int

Требовать TLS управляющего соединения, иначе отказ. Канал данных FTP этим требованием не защищён автоматически.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPSSL_CONTROL; libcurl: CURLOPT_USE_SSL

CURLFTPSSL_NONE
Тип самой константы: int

Не пытаться включить TLS для соответствующего протокола. Старое имя CURLUSESSL_NONE.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPSSL_NONE; libcurl: CURLOPT_USE_SSL

CURLFTPSSL_TRY
Тип самой константы: int

Попытаться TLS, но продолжить без него при невозможности. Сервер может закрыть соединение после неуспешного согласования; для обязательной защиты TRY не подходит.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLFTPSSL_TRY; libcurl: CURLOPT_USE_SSL

CURLFTP_CREATE_DIR
Тип самой константы: int

Если переход/открытие каталога не удались, попытаться создать его; права и существующий одноимённый файл могут помешать.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.19.3

PHP: CURLFTP_CREATE_DIR; libcurl: CURLOPT_FTP_CREATE_MISSING_DIRS

CURLFTP_CREATE_DIR_NONE
Тип самой константы: int

Не создавать отсутствующие каталоги FTP/SFTP; default.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.19.3

PHP: CURLFTP_CREATE_DIR_NONE; libcurl: CURLOPT_FTP_CREATE_MISSING_DIRS

CURLFTP_CREATE_DIR_RETRY
Тип самой константы: int

После неуспешного создания снова попробовать перейти: полезно, когда другой параллельный клиент уже успел создать каталог. Не скрывает произвольную ошибку прав.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.19.3

PHP: CURLFTP_CREATE_DIR_RETRY; libcurl: CURLOPT_FTP_CREATE_MISSING_DIRS

CURLOPT_ACCEPTTIMEOUT_MS
Тип самой константы: int

Предел ожидания обратного соединения сервера при active FTP. В passive FTP клиент сам соединяется с сервером, поэтому эта настройка там не нужна. Это не общий timeout всей передачи.

Значение/результат: int, миллисекунды.

По умолчанию: 60000.

Версии: Доступно с libcurl 7.24.0. Native API: libcurl 7.24.0.

PHP: CURLOPT_ACCEPTTIMEOUT_MS; libcurl: CURLOPT_ACCEPTTIMEOUT_MS

CURLOPT_APPEND
Тип самой константы: int

При загрузке FTP дописывает удалённый файл вместо замены. Это побочный эффект на сервере: повтор запроса может повторно дописать те же данные. Не превращает HTTP POST в append.

Значение/результат: bool/int 0|1.

По умолчанию: false.

Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0.

PHP: CURLOPT_APPEND; libcurl: CURLOPT_APPEND

CURLOPT_DIRLISTONLY
Тип самой константы: int

FTP/SFTP: список имён без размеров/дат; FTP использует NLST, поэтому некоторые серверы не включают каталоги/ссылки. Сам флаг подразумевает listing даже без конечного /. POP3: список сообщений/размера сообщения вместо получения тела. FILE-каталоги уже перечисляются так. Конфликтует с WILDCARDMATCH и лишает его эффекта.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0.

PHP: CURLOPT_DIRLISTONLY; libcurl: CURLOPT_DIRLISTONLY

CURLOPT_FTPAPPEND
Тип самой константы: int

Старое имя APPEND: дописать файл при FTP upload вместо overwrite; повтор может дублировать данные. Deprecated native-имя с7.16.4, для нового кода APPEND.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.16.4. Native API CURLOPT_APPEND: libcurl 7.17.0.

PHP: CURLOPT_FTPAPPEND; libcurl: CURLOPT_APPEND

CURLOPT_FTPLISTONLY
Тип самой константы: int

Старое имя DIRLISTONLY: FTP NLST вместо подробного LIST. С7.16.4 deprecated native-имя; новое DIRLISTONLY также описывает SFTP/POP3. Некоторые FTP-серверы исключают каталоги/ссылки из NLST.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.16.4. Native API CURLOPT_DIRLISTONLY: libcurl 7.17.0.

PHP: CURLOPT_FTPLISTONLY; libcurl: CURLOPT_DIRLISTONLY

CURLOPT_FTPPORT
Тип самой константы: int

Включает active FTP: сервер соединяется обратно с адресом клиента. Допустимы IP, hostname, Unix interface или "-" для системного адреса; можно добавить :port либо :first-last, IPv6 с портом — [::1]:port. Port0 выбирает ОС, занятый диапазон ведёт к FTP_PORT_FAILED. Ошибочный формат port/range native может проигнорировать, поэтому проверять самим. Hostname вызывает блокирующий DNS без DoH. null возвращает passive; через NAT active требует сознательной сетевой настройки.

Значение/результат: string|null.

По умолчанию: null: passive FTP.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_FTPPORT; libcurl: CURLOPT_FTPPORT

CURLOPT_FTPSSLAUTH
Тип самой константы: int

При USE_SSL выбирает порядок AUTH SSL/AUTH TLS: DEFAULT решает библиотека, SSL сначала AUTH SSL, TLS сначала AUTH TLS; при неудаче пробуется другой. Это текст FTP-команды, не выбор SSLv3/TLS1.3 криптопротокола.

Значение/результат: int CURLFTPAUTH_*.

По умолчанию: CURLFTPAUTH_DEFAULT.

Версии: Доступно с libcurl 7.12.2. Native API: libcurl 7.12.2.

PHP: CURLOPT_FTPSSLAUTH; libcurl: CURLOPT_FTPSSLAUTH

CURLOPT_FTP_ACCOUNT
Тип самой константы: int

Account data для FTP ACCT, когда сервер просит их после USER/PASS. Это отдельное поле от username/password; null отключает. Не выводить вместе с диагностикой credentials.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.13.0. Native API: libcurl 7.13.0.

PHP: CURLOPT_FTP_ACCOUNT; libcurl: CURLOPT_FTP_ACCOUNT

CURLOPT_FTP_ALTERNATIVE_TO_USER
Тип самой константы: int

Дополнительная строка FTP-аутентификации после провала обычного USER/PASS. Специализированная совместимость, в документации — Tumbleweed Secure Transport FTPS с клиентским сертификатом. Не вставлять произвольные команды пользователя.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.15.5. Native API: libcurl 7.15.5.

PHP: CURLOPT_FTP_ALTERNATIVE_TO_USER; libcurl: CURLOPT_FTP_ALTERNATIVE_TO_USER

CURLOPT_FTP_CREATE_MISSING_DIRS
Тип самой константы: int

Разрешает создать недостающий удалённый каталог FTP/SFTP. DIR=1 пробует создание после провала CWD/получения target handle; RETRY=2 повторяет CWD, если MKD проиграл гонку другой загрузке. Файл с тем же именем или недостаточные права остаются ошибкой. Это запись на сервере, не проверка существования.

Значение/результат: int CURLFTP_CREATE_DIR_*.

По умолчанию: NONE=0.

Версии: Доступно с libcurl 7.10.7. Native API: libcurl 7.10.7.

PHP: CURLOPT_FTP_CREATE_MISSING_DIRS; libcurl: CURLOPT_FTP_CREATE_MISSING_DIRS

CURLOPT_FTP_FILEMETHOD
Тип самой константы: int

Как добраться до FTP(S)-файла: MULTICWD меняет каталог по каждому компоненту пути; SINGLECWD делает один CWD на полный каталог; NOCWD использует полный путь в SIZE/RETR/STOR без CWD. Быстрее не всегда совместимее с конкретным сервером. NONE — служебное значение перечисления, не четвёртая рекомендуемая стратегия.

Значение/результат: int CURLFTPMETHOD_*.

По умолчанию: MULTICWD.

Версии: Доступно с libcurl 7.15.1. Native API: libcurl 7.15.1.

PHP: CURLOPT_FTP_FILEMETHOD; libcurl: CURLOPT_FTP_FILEMETHOD

CURLOPT_FTP_SKIP_PASV_IP
Тип самой константы: int

При PASV игнорирует IP из ответа227 и соединяется для данных с IP контрольного канала, сохраняя предложенный port. Помогает NAT и уменьшает перенаправление к чужому узлу злонамеренным сервером. Не влияет на PORT/EPRT/EPSV.

Значение/результат: bool.

По умолчанию: true с7.74; раньше false.

Версии: Доступно с libcurl 7.15.0. Native API: libcurl 7.15.0.

PHP: CURLOPT_FTP_SKIP_PASV_IP; libcurl: CURLOPT_FTP_SKIP_PASV_IP

CURLOPT_FTP_SSL
Тип самой константы: int

Исторический alias USE_SSL, deprecated-имя с7.16.4. NONE без TLS, TRY допускает незашифрованное продолжение, CONTROL защищает только FTP control, ALL требует защиты всех каналов. Для новых клиентов использовать USE_SSL; TRY/CONTROL не дают полной защиты.

Значение/результат: int CURLUSESSL_*.

По умолчанию: NONE.

Версии: Доступно с libcurl 7.11.0 and deprecated as of libcurl 7.16.4. Native API CURLOPT_USE_SSL: libcurl 7.17.0.

PHP: CURLOPT_FTP_SSL; libcurl: CURLOPT_USE_SSL

CURLOPT_FTP_SSL_CCC
Тип самой константы: int

Clear Command Channel снимает TLS после аутентификации, оставляя FTP control незашифрованным ради некоторых NAT. NONE не делать; PASSIVE ждать shutdown сервера без ответа; ACTIVE инициировать и ждать ответ. Это сознательное ослабление защиты, не настройка сертификата.

Значение/результат: int CURLFTPSSL_CCC_*.

По умолчанию: NONE.

Версии: Доступно с libcurl 7.16.1. Native API: libcurl 7.16.1.

PHP: CURLOPT_FTP_SSL_CCC; libcurl: CURLOPT_FTP_SSL_CCC

CURLOPT_FTP_USE_EPRT
Тип самой константы: int

Для active FTP сначала пробовать EPRT, затем PORT. false оставляет PORT; на IPv6 EPRT необходим и отключение не действует. Старые описания упоминают также LPRT; современный выбор строится вокруг EPRT/PORT.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с libcurl 7.10.5. Native API: libcurl 7.10.5.

PHP: CURLOPT_FTP_USE_EPRT; libcurl: CURLOPT_FTP_USE_EPRT

CURLOPT_FTP_USE_EPSV
Тип самой константы: int

Для passive FTP сначала EPSV, затем PASV. false отключает EPSV только там, где возможен PASV; на IPv6 ограничение не действует. Отключать ради подтверждённой совместимости сервера, а не как универсальное лечение FTP.

Значение/результат: bool.

По умолчанию: true.

Версии: Доступно с libcurl 7.9.2. Native API: libcurl 7.9.2.

PHP: CURLOPT_FTP_USE_EPSV; libcurl: CURLOPT_FTP_USE_EPSV

CURLOPT_FTP_USE_PRET
Тип самой константы: int

Посылать нестандартную PRET перед PASV/EPSV, что нужно некоторым серверам, например drftpd, при listing/upload/download. В active FTP эффекта нет.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_FTP_USE_PRET; libcurl: CURLOPT_FTP_USE_PRET

CURLOPT_POSTQUOTE
Тип самой константы: int

FTP/SFTP-команды после успешной передачи; при ошибке передачи не исполняются. Синтаксис/возможные изменения файлов описывает QUOTE. Последний список заменяет прежний. Это реальные операции на сервере, не безвредный текстовый post-hook.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_POSTQUOTE; libcurl: CURLOPT_POSTQUOTE

CURLOPT_PREQUOTE
Тип самой константы: int

FTP-команды после выбора transfer type, до файлового обмена; не для directory listing. В отличие от QUOTE/POSTQUOTE не применяется к SFTP. Последний список заменяет прежний; внешние значения не превращать в команды.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.9.5. Native API: libcurl 7.9.5.

PHP: CURLOPT_PREQUOTE; libcurl: CURLOPT_PREQUOTE

CURLOPT_PROXY_TRANSFER_MODE
Тип самой константы: int

Для FTP URL через HTTP proxy добавляет ;type=a либо ;type=i, чтобы передать выбор TRANSFERTEXT. Без флага TRANSFERTEXT при таком маршруте не действует. Proxy обязан понимать расширение; это не FTP tunnel.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.18.0. Native API: libcurl 7.18.0.

PHP: CURLOPT_PROXY_TRANSFER_MODE; libcurl: CURLOPT_PROXY_TRANSFER_MODE

CURLOPT_QUOTE
Тип самой константы: int

FTP/SFTP-команды до передачи, для FTP даже до CWD. FTP-команды передаются буквально; изменение состояния/каталога неизвестно libcurl, префикс* разрешает продолжить после отказа команды. Не использовать ввод HTTP-пользователя как команду. SFTP поддерживает atime/mtime date file (с 7.73), chgrp decimalGroup file, chmod octalMode file, chown decimalUser file, ln/symlink source target, mkdir directory, pwd, rename source target, rm file, rmdir emptyDirectory, statvfs file. Пути с пробелами/спецсимволами требуют quoted-синтаксиса SFTP; это не shell escaping. Удаление/переименование реально меняют сервер. Последний список заменяет прежний.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_QUOTE; libcurl: CURLOPT_QUOTE

CURLOPT_TRANSFERTEXT
Тип самой константы: int

Для FTP просить ASCII transfer mode вместо binary. Это выбор режима протокола, а не полноценная перекодировка Unicode текста силами PHP. PHP-документация также описывает исторический LDAP plain-text вывод вместо HTML; поведение зависит от протокола/сборки. Для бинарных файлов режим должен оставаться выключенным.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.1. Native API: libcurl 7.1.1.

PHP: CURLOPT_TRANSFERTEXT; libcurl: CURLOPT_TRANSFERTEXT

CURLOPT_USE_SSL
Тип самой константы: int

STARTTLS/переход на TLS для FTP, SMTP, POP3, IMAP и подходящих протоколов. TRY допускает продолжение без TLS; CONTROL защищает только управляющий FTP-канал, для других протоколов эквивалентен ALL. ALL требует TLS; отказ может иметь native код CURLE_USE_SSL_FAILED (в PHP для него есть историческое имя CURLE_FTP_SSL_FAILED). Для обычного HTTPS TLS выбирает схема URL.

Значение/результат: int: CURLUSESSL_*.

По умолчанию: CURLUSESSL_NONE.

Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0.

PHP: CURLOPT_USE_SSL; libcurl: CURLOPT_USE_SSL

CURLOPT_WILDCARDMATCH
Тип самой константы: int

Для FTP использовать шаблон последней части пути и передавать подходящие файлы: * — последовательность, ? — один символ, [a-z]/[abc] — класс, [!abc] — исключение. Native синтаксис ограничивает число * и имеет собственные правила скобок, не равен регулярному выражению. FNMATCH_FUNCTION позволяет заменить сравнение. DIRLISTONLY меняет сценарий; не считайте wildcard универсальным способом получения HTTP-каталога.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.21.0. Native API: libcurl 7.21.0.

PHP: CURLOPT_WILDCARDMATCH; libcurl: CURLOPT_WILDCARDMATCH

CURLUSESSL_ALL
Тип самой константы: int

Требовать TLS и для управления, и для данных, иначе отказ. Для чтения ошибки libcurl использует USE_SSL_FAILED; не путать с простым наличием HTTPS в URL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.17.0.

PHP: CURLUSESSL_ALL; libcurl: CURLOPT_USE_SSL

CURLUSESSL_CONTROL
Тип самой константы: int

Требовать TLS управляющего соединения, иначе отказ. Канал данных FTP этим требованием не защищён автоматически.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.17.0.

PHP: CURLUSESSL_CONTROL; libcurl: CURLOPT_USE_SSL

CURLUSESSL_NONE
Тип самой константы: int

Не пытаться включить TLS для соответствующего протокола.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.17.0.

PHP: CURLUSESSL_NONE; libcurl: CURLOPT_USE_SSL

CURLUSESSL_TRY
Тип самой константы: int

Попытаться TLS, но продолжить без него при невозможности. Сервер может закрыть соединение после неуспешного согласования; для обязательной защиты TRY не подходит.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.17.0.

PHP: CURLUSESSL_TRY; libcurl: CURLOPT_USE_SSL

SFTP/SCP: ключ сервера и вход клиента

Здесь два вопроса: тот ли это сервер и имеет ли клиент право войти. KNOWNHOSTS/fingerprint/HOSTKEYFUNCTION проверяют сервер, PRIVATE_KEYFILE/PUBLIC_KEYFILE/AUTH_TYPES — клиента. Проверка нового соединения не означает повторную проверку каждого запроса при reuse. Не превращайте ошибку host key в callback, всегда возвращающий OK.

Подключиться к известному SFTP серверу
  1. Заранее доверенный host key записан в known_hosts
  2. При новом соединении сравнивается ключ сервера
  3. Затем клиент подтверждает свой вход ключом/разрешённым методом
  4. Только после этого передаётся файл
КонстантаНазначение, договор и границы
CURLKHMATCH_LAST
Тип самой константы: int

Служебная граница перечисления; не настоящий исход проверки host key и не разрешённая политика доверия.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.3.0 и libcurl 7.19.6

PHP: CURLKHMATCH_LAST; libcurl: CURLOPT_SSH_HOSTKEYFUNCTION

CURLKHMATCH_MISMATCH
Тип самой константы: int

Callback отвергает серверный host key; соединение отменяется.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.3.0 и libcurl 7.19.6

PHP: CURLKHMATCH_MISMATCH; libcurl: CURLOPT_SSH_HOSTKEYFUNCTION

CURLKHMATCH_MISSING
Тип самой константы: int

Значение перечисления для отсутствующего известного ключа; не считать его разрешением принять любой новый ключ. У HOSTKEYFUNCTION документированные ответы — OK или MISMATCH.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.3.0 и libcurl 7.19.6

PHP: CURLKHMATCH_MISSING; libcurl: CURLOPT_SSH_HOSTKEYFUNCTION

CURLKHMATCH_OK
Тип самой константы: int

Callback проверки host key принимает серверный ключ: соединение может продолжаться. Возвращать только после реальной проверки доверия.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.3.0 и libcurl 7.19.6

PHP: CURLKHMATCH_OK; libcurl: CURLOPT_SSH_HOSTKEYFUNCTION

CURLOPT_SSH_AUTH_TYPES
Тип самой константы: int

Разрешённые способы SSH-входа: publickey,password,keyboard,agent и доступные backend методы. Native отмечает, что AUTH_HOST сейчас не имеет эффекта; agent может быть ssh-agent или Pageant. Не проверяет host key сервера — это отдельные KNOWNHOSTS/hash/callback настройки.

Значение/результат: int-маска CURLSSH_AUTH_*.

По умолчанию: ANY.

Версии: Доступно с libcurl 7.16.1. Native API: libcurl 7.16.1.

PHP: CURLOPT_SSH_AUTH_TYPES; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLOPT_SSH_COMPRESSION
Тип самой константы: int

Просит встроенное SSH-сжатие, сервер вправе не согласиться. Не гарантирует экономию или ускорение; это не HTTP Content-Encoding.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.56.0. Native API: libcurl 7.56.0.

PHP: CURLOPT_SSH_COMPRESSION; libcurl: CURLOPT_SSH_COMPRESSION

CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
Тип самой константы: int

Старый MD5 fingerprint SSH hostkey для SCP/SFTP. MD5 слаб, предпочитать SHA256/KNOWNHOSTS. Проверяется при новом соединении вместо knownhosts/callback пути, не как обязательная дополнительная проверка. Изменение не перепроверяет уже пригодное кешированное соединение.

Значение/результат: string|null: 32 hex-символа.

По умолчанию: null.

Версии: Доступно с libcurl 7.17.1. Native API: libcurl 7.17.1.

PHP: CURLOPT_SSH_HOST_PUBLIC_KEY_MD5; libcurl: CURLOPT_SSH_HOST_PUBLIC_KEY_MD5

CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256
Тип самой константы: int

Ожидаемый hash SSH hostkey; несовпадение запрещает новую SSH-сессию. Значение — Base64 SHA256, не TLS-формат sha256// и не hex. При этом режиме knownhosts/callback/MD5 дополнительно не суммируются; уже проверенное соединение может reuse без повторной проверки. Ротация требует продуманной политики и при необходимости нового соединения.

Значение/результат: string|null:Base64 SHA256.

По умолчанию: null.

Версии: Доступно с PHP 8.2.0 и libcurl 7.80.0. Native API: libcurl 7.80.0.

PHP: CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256; libcurl: CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256

CURLOPT_SSH_KNOWNHOSTS
Тип самой константы: int

Разрешает известные hosts с совпавшим ключом по указанному файлу. Проверка только при новом SSH-соединении; смена файла/политики не переверифицирует кешированное. Для принудительной новой проверки использовать FRESH_CONNECT/FORBID_REUSE. HOSTKEYFUNCTION или hash-политики могут заменить этот путь.

Значение/результат: string|null:OpenSSH known_hosts.

По умолчанию: null.

Версии: Доступно с libcurl 7.19.6. Native API: libcurl 7.19.6.

PHP: CURLOPT_SSH_KNOWNHOSTS; libcurl: CURLOPT_SSH_KNOWNHOSTS

CURLOPT_SSH_PRIVATE_KEYFILE
Тип самой константы: int

Клиентский приватный SSH-ключ; password-protected ключ требует KEYPASSWD. Backend может вывести публичный ключ из приватного; если не умеет и PUBLIC_KEYFILE отсутствует, запрос откажет. Старый PHP текст перечисляет лишь id_dsa; для воспроизводимости задавать явный путь современного ключа. Новое значение применяется к новому входу, не обязано отменять reuse.

Значение/результат: string|null:файл ключа.

По умолчанию: backend-поиск $HOME/.ssh/id_rsa или id_dsa; без HOME текущий каталог.

Версии: Доступно с libcurl 7.16.1. Native API: libcurl 7.16.1.

PHP: CURLOPT_SSH_PRIVATE_KEYFILE; libcurl: CURLOPT_SSH_PRIVATE_KEYFILE

CURLOPT_SSH_PUBLIC_KEYFILE
Тип самой константы: int

Публичный ключ клиента, не hostkey сервера. null/"" позволяет SSH backend вывести его из приватного ключа; если невозможно, требуется файл. Старые описания поиска $HOME/.ssh/id_dsa.pub не универсальны для современных backend. Настройка относится к новому соединению.

Значение/результат: string|null:файл публичного ключа.

По умолчанию: современный native NULL; исторически id_dsa.pub.

Версии: Доступно с libcurl 7.16.1. Native API: libcurl 7.16.1.

PHP: CURLOPT_SSH_PUBLIC_KEYFILE; libcurl: CURLOPT_SSH_PUBLIC_KEYFILE

CURLSSH_AUTH_AGENT
Тип самой константы: int

Разрешить ключи SSH agent. Доступ к агенту и выбор ключа — дополнительные предпосылки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.28.0

PHP: CURLSSH_AUTH_AGENT; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_ANY
Тип самой константы: int

Разрешить любой поддерживаемый SSH-метод; сервер/сборка выбирают конкретный.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_ANY; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_DEFAULT
Тип самой константы: int

Стандартный выбор допустимых SSH-методов, соответствует ANY.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_DEFAULT; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_GSSAPI
Тип самой константы: int

Разрешить SSH GSS-API, если сборка backend имеет такую возможность.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.58.0

PHP: CURLSSH_AUTH_GSSAPI; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_HOST
Тип самой константы: int

Исторически host-based SSH-аутентификация; текущая libcurl отмечает, что этот бит не имеет эффекта. Это не проверка host key сервера.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_HOST; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_KEYBOARD
Тип самой константы: int

Интерактивный keyboard authentication; поведение/поддержка зависят от SSH backend.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_KEYBOARD; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_NONE
Тип самой константы: int

Нулевая маска без SSH-аутентификации.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_NONE; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_PASSWORD
Тип самой константы: int

Разрешить SSH-аутентификацию паролем.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_PASSWORD; libcurl: CURLOPT_SSH_AUTH_TYPES

CURLSSH_AUTH_PUBLICKEY
Тип самой константы: int

Разрешить SSH-аутентификацию клиентским публичным ключом; ключевые файлы задаются отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURLSSH_AUTH_PUBLICKEY; libcurl: CURLOPT_SSH_AUTH_TYPES

SMTP: отправитель и получатели

SMTP envelope отправителя/получателей отличается от видимых From/To заголовков самого сообщения. MAIL_FROM и MAIL_RCPT управляют envelope; тело сообщения поступает через upload. Отказ одного получателя не всегда означает отказ всех: политика MAIL_RCPT_ALLLOWFAILS требует продуманного учёта результата и повторов.

Envelope письма
  1. MAIL_FROM задаёт отправителя доставки
  2. MAIL_RCPT перечисляет адресатов доставки
  3. Сервер принимает или отвергает каждого адресата
  4. Только затем передаётся подготовленное сообщение
КонстантаНазначение, договор и границы
CURLOPT_MAIL_AUTH
Тип самой константы: int

AUTH identity пересылаемого SMTP-сообщения для доверенных взаимодействующих mail servers. Не обычный login/password. Передаётся без <скобок>; "" даёт <> поRFC2554, когда identity неизвестна/непригодна. Использовать только когда приложение само relay в таком доверенном окружении.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.25.0. Native API: libcurl 7.25.0.

PHP: CURLOPT_MAIL_AUTH; libcurl: CURLOPT_MAIL_AUTH

CURLOPT_MAIL_FROM
Тип самой константы: int

Адрес SMTP envelope sender, предпочтительно <user@example.test>; скобки добавляются для одиночного адреса. DSN-параметрыRFC3461 пишутся после адреса в явных скобках. Без настройки пустой адрес может быть отклонён. Это не автоматическое создание видимого From: в тексте письма.

Значение/результат: string|null.

По умолчанию: пустой envelope sender.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_MAIL_FROM; libcurl: CURLOPT_MAIL_FROM

CURLOPT_MAIL_RCPT
Тип самой константы: int

SMTP envelope recipients, каждый <address>; одиночный адрес без < получает скобки автоматически. DSN-параметры требуют явных скобок перед ними. Для VRFY передаётся username/user@domain, для EXPN — имя рассылки. Не равно видимому To: header; последний список заменяет прежний.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_MAIL_RCPT; libcurl: CURLOPT_MAIL_RCPT

CURLOPT_MAIL_RCPT_ALLLOWFAILS
Тип самой константы: int

Разрешает продолжить SMTP при отказе некоторым RCPT TO, отправив принятым получателям. Если отклонены все, передача прерывается с последним отказом. В PHP8.5.11 экспортируется историческое имя с тремя L: ALLLOWFAILS. Native с8.2 исправил его на MAIL_RCPT_ALLOWFAILS; новый native-символ не гарантирован в PHP. Успешная передача здесь не доказывает доставку всем исходным получателям.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 8.2.0 и libcurl 7.69.0. Устарело с libcurl 8.2.0. Native API CURLOPT_MAIL_RCPT_ALLOWFAILS: libcurl 8.2.0.

PHP: CURLOPT_MAIL_RCPT_ALLLOWFAILS; libcurl: CURLOPT_MAIL_RCPT_ALLOWFAILS

RTSP: сессия медиапотока

RTSP управляет воспроизведением/записью, а не является обычным скачиванием видео по HTTP. DESCRIBE получает описание, SETUP согласует транспорт/сессию, PLAY запускает её. Session ID и CSeq связывают последующие команды; приложению нужен договор конкретного сервера и понимание RTP.

Управление воспроизведением
  1. DESCRIBE → описание потока
  2. SETUP → транспорт и Session ID
  3. PLAY с Session ID → начать
  4. PAUSE/TEARDOWN → остановить или завершить
КонстантаНазначение, договор и границы
CURLOPT_RTSP_CLIENT_CSEQ
Тип самой константы: int

Начальный номер следующей RTSP-команды, затем автоматически увеличивается. Нужен для восстановления существующей сессии после потери соединения, а не для произвольной нумерации PHP массива.

Значение/результат: int.

По умолчанию: 0.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_RTSP_CLIENT_CSEQ; libcurl: CURLOPT_RTSP_CLIENT_CSEQ

CURLOPT_RTSP_REQUEST
Тип самой константы: int

Выбор RTSP-команды. Обычно нужна Session ID; OPTIONS/DESCRIBE/первый SETUP могут работать без неё. SETUP требует TRANSPORT и сохраняет серверный session ID. SET_PARAMETER/ANNOUNCE используют upload/read source или POSTFIELDS со знакомым размером; chunked и multipartRTSP не поддерживаются. RECEIVE только получает interleavedRTP и возвращает управление после read buffer. Все 11 значений разъяснены отдельно.

Значение/результат: int CURL_RTSPREQ_*.

По умолчанию: OPTIONS в native.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_RTSP_REQUEST; libcurl: CURLOPT_RTSP_REQUEST

CURLOPT_RTSP_SERVER_CSEQ
Тип самой константы: int

Ожидаемый номер следующей команды server→client. Само прослушивание инициированных сервером RTSP-запросов в libcurl не реализовано; наличие настройки не обещает готовый server-event listener.

Значение/результат: int.

По умолчанию: 0.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_RTSP_SERVER_CSEQ; libcurl: CURLOPT_RTSP_SERVER_CSEQ

CURLOPT_RTSP_SESSION_ID
Тип самой константы: int

Session ID текущей RTSP-сессии; при заданном значении несовпадение ответа ведёт к native CURLE_RTSP_SESSION_ERROR. null позволяет принять первый serverID. При смене origin на reusedhandle очистить/заменить ID; текущий native отправляет его исходному origin, если не включён UNRESTRICTED_AUTH. Не логировать как безвредный номер.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_RTSP_SESSION_ID; libcurl: CURLOPT_RTSP_SESSION_ID

CURLOPT_RTSP_STREAM_URI
Тип самой константы: int

Какой stream URI указать в RTSP request, отдельно от URL соединения. Одна сессия может переключаться между audio/video paths. Не задано — общие опции сервера через*.

Значение/результат: string|null.

По умолчанию: *.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_RTSP_STREAM_URI; libcurl: CURLOPT_RTSP_STREAM_URI

CURLOPT_RTSP_TRANSPORT
Тип самой константы: int

Значение RTSP Transport header; обязателен до SETUP. Это согласованное описание transport parameters, не URL сервера. Приложение выбирает поддерживаемый обеими сторонами режим.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.20.0. Native API: libcurl 7.20.0.

PHP: CURLOPT_RTSP_TRANSPORT; libcurl: CURLOPT_RTSP_TRANSPORT

CURL_RTSPREQ_ANNOUNCE
Тип самой константы: int

Передать/изменить описание сессии. При отправке клиентом тело настраивается по модели HTTP PUT/POST, как у SET_PARAMETER.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_ANNOUNCE; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_DESCRIBE
Тип самой константы: int

Получить описание медиапотока. В Accept указывают понимаемые форматы; без собственного заголовка libcurl добавляет application/sdp. Для DESCRIBE применяются условные time headers из TIMECONDITION.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_DESCRIBE; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_GET_PARAMETER
Тип самой константы: int

Получить параметр сервера. Непустое тело по умолчанию получает Content-Type: text/parameters, если не задан другой. Работа с телом похожа на HTTP PUT/POST; пустой GET_PARAMETER используют как heartbeat.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_GET_PARAMETER; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_OPTIONS
Тип самой константы: int

Запросить поддерживаемые сервером RTSP методы.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_OPTIONS; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_PAUSE
Тип самой константы: int

Поставить воспроизведение на паузу. Один момент RANGE, например npt=25, задаёт время остановки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_PAUSE; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_PLAY
Тип самой константы: int

Начать воспроизведение. RANGE может задать интервал, например npt=10-15.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_PLAY; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_RECEIVE
Тип самой константы: int

Принимать interleaved RTP data. Это особый режим получения данных, а не отправка команды PLAY.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_RECEIVE; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_RECORD
Тип самой константы: int

Попросить сервер записывать сессию; RANGE уточняет временной интервал записи.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_RECORD; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_SETUP
Тип самой константы: int

Настроить транспорт сессии; детали передаются отдельно через RTSP_TRANSPORT.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_SETUP; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_SET_PARAMETER
Тип самой константы: int

Установить параметр RTSP-сервера; тело и его Content-Type задаются приложением.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_SET_PARAMETER; libcurl: CURLOPT_RTSP_REQUEST

CURL_RTSPREQ_TEARDOWN
Тип самой константы: int

Завершить RTSP-сессию. Закрыть TCP-соединение недостаточно: одна сессия может управляться через разные соединения.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.20.0.

PHP: CURL_RTSPREQ_TEARDOWN; libcurl: CURLOPT_RTSP_REQUEST

TELNET, TFTP и WebSocket

Эти протоколы решают отдельные задачи: TELNET согласует терминал, TFTP передаёт файлы по простому протоколу, WebSocket обменивается кадрами после установления соединения. Наличие CURLWS_RAW_MODE не создаёт недостающие PHP-методы native WebSocket API. Сначала проверяйте protocols и требуемую модель обмена.

Выбор специального протокола
  1. Устройство/сервис задаёт реальный протокол
  2. curl_version показывает возможности сборки
  3. Опции настраивают только этот протокол
  4. Кадры, блоки или терминальные параметры имеют собственные правила
КонстантаНазначение, договор и границы
CURLOPT_TELNETOPTIONS
Тип самой константы: int

Список строк option=value для TELNET: TTYPE — тип терминала, XDISPLOC — display, NEW_ENV — переменная окружения. Повторная установка заменяет прежний список. Это протокольные параметры, не команды оболочки; TELNET не обеспечивает конфиденциальность как SSH.

Значение/результат: array<string>.

По умолчанию: пустой список.

Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7.

PHP: CURLOPT_TELNETOPTIONS; libcurl: CURLOPT_TELNETOPTIONS

CURLOPT_TFTP_BLKSIZE
Тип самой константы: int

Запрашиваемый размер блока TFTP. Сервер должен согласовать расширение; при отказе используется базовый размер 512. Большой блок не гарантирует ускорение в сети с потерями. TFTP_NO_OPTIONS отключает согласование и делает этот выбор недействующим.

Значение/результат: int: 8…65464 байта.

По умолчанию: 512.

Версии: Доступно с libcurl 7.19.4. Native API: libcurl 7.19.4.

PHP: CURLOPT_TFTP_BLKSIZE; libcurl: CURLOPT_TFTP_BLKSIZE

CURLOPT_TFTP_NO_OPTIONS
Тип самой константы: int

Не отправлять TFTP option negotiation (RFC 2347/2348/2349) в запросах чтения/записи. Нужно для некоторых старых серверов; тогда используется базовый размер блока и TFTP_BLKSIZE игнорируется. Это режим совместимости, не защита передаваемых данных.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.48.0. Native API: libcurl 7.48.0.

PHP: CURLOPT_TFTP_NO_OPTIONS; libcurl: CURLOPT_TFTP_NO_OPTIONS

CURLOPT_WS_OPTIONS
Тип самой константы: int

Настройки WebSocket. Экспортированный PHP бит CURLWS_RAW_MODE отдаёт приложению сырые framing-данные, и оно отвечает за кадры/управляющие сообщения. Наличие константы не означает наличие полноценных PHP-обёрток native curl_ws_send/recv. Проверяйте ws/wss в curl_version protocols; новые native биты могут ещё не экспортироваться в PHP.

Значение/результат: int: маска CURLWS_*.

По умолчанию: 0.

Версии: Доступно с PHP 8.3.0 и libcurl 7.86.0. Native API: libcurl 7.86.0.

PHP: CURLOPT_WS_OPTIONS; libcurl: CURLOPT_WS_OPTIONS

CURLWS_RAW_MODE
Тип самой константы: int

Бит raw WebSocket: callbacks получают/передают сырые frames, libcurl не обрабатывает ping и остальные frames за приложение. Это не обычный текст сообщения; приложение отвечает за framing. Наличие ws/wss проверять в curl_version.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.3.0 и libcurl 7.86.0

PHP: CURLWS_RAW_MODE; libcurl: CURLOPT_WS_OPTIONS

Multi: параллельность, соединения и результаты

Multi управляет несколькими easy handles. Лимит одновременных соединений, размер сохраняемого пула и число HTTP/2/3 потоков — разные пределы. CURLM_* сообщает о работе multi API; результат отдельной передачи всё ещё CURLE_*. CURLMSG_DONE обозначает сообщение о завершении, которое надо прочитать, а не успех любого ответа.

Несколько загрузок в одном multi
  1. Добавить независимые easy handles
  2. Применить лимиты соединений/потоков
  3. Продвигать multi и ожидать события
  4. Прочитать CURLMSG_DONE каждого handle
  5. Проверить его CURLE результат и прикладной HTTP-ответ

Практика полного цикла: curl_multi_exec, curl_multi_info_read и curl_multi_setopt.

КонстантаНазначение, договор и границы
CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE
Тип самой константы: int

int, исторический default 0 — штраф отключён. Порог текущего chunk в байтах: pipeline с более крупным chunk не выбирался для новых запросов. После удаления pipelining в libcurl 7.62.0 настройка не действует; HTTP/2 multiplexing ею не настраивается.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 7.0.7 и libcurl 7.30.0 Native API: libcurl 7.30.0.

PHP: CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE; libcurl: CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE

CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE
Тип самой константы: int

int, исторический default 0 — штраф отключён. Порог Content-Length ответа в байтах: pipeline с более крупным текущим ответом не выбирался для новых запросов. После удаления pipelining в libcurl 7.62.0 настройка не действует; HTTP/2 multiplexing ею не настраивается.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 7.0.7 и libcurl 7.30.0 Native API: libcurl 7.30.0.

PHP: CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE; libcurl: CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE

CURLMOPT_MAXCONNECTS
Тип самой константы: int

Значение int задаёт предел кеша повторно используемых соединений multi, а не предел одновременно активных запросов. PHP Manual описывает исторический автопредел как 4 × число добавленных handles; актуальная native-страница описывает 2 × число handles. При явном пределе из заполненного кеша удаляется старейшее соединение. Для активных соединений нужен MAX_TOTAL_CONNECTIONS; не полагаться на один неизменный множитель между версиями.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с libcurl 7.16.3. Native API: libcurl 7.16.3.

PHP: CURLMOPT_MAXCONNECTS; libcurl: CURLMOPT_MAXCONNECTS

CURLMOPT_MAX_CONCURRENT_STREAMS
Тип самой константы: int

int от 1 до 2147483647, по умолчанию 100: желаемый максимум параллельных streams HTTP/2 и в актуальном libcurl HTTP/3. Возможности сервера и ресурсов могут дать меньший фактический предел.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 8.2.0 и libcurl 7.67.0. Native API: libcurl 7.67.0.

PHP: CURLMOPT_MAX_CONCURRENT_STREAMS; libcurl: CURLMOPT_MAX_CONCURRENT_STREAMS

CURLMOPT_MAX_HOST_CONNECTIONS
Тип самой константы: int

int: максимум соединений к паре host + port; 0 по умолчанию — без этого ограничения. При proxy учитывается proxy как host. Излишние передачи ждут в очереди; общее время ожидания входит в TIMEOUT_MS, ограничение CONNECTTIMEOUT_MS тоже может истечь до разрешения соединения. Уменьшение предела не закрывает уже активные передачи.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 7.0.7 и libcurl 7.30.0 Native API: libcurl 7.30.0.

PHP: CURLMOPT_MAX_HOST_CONNECTIONS; libcurl: CURLMOPT_MAX_HOST_CONNECTIONS

CURLMOPT_MAX_PIPELINE_LENGTH
Тип самой константы: int

int, исторический default 5. Максимум ожидающих ответов HTTP/1.1 внутри одного pipeline; при превышении libcurl создавал другое соединение или ставил запрос в очередь. После удаления pipelining в libcurl 7.62.0 настройка не действует; HTTP/2 multiplexing ею не настраивается.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 7.0.7 и libcurl 7.30.0 Native API: libcurl 7.30.0.

PHP: CURLMOPT_MAX_PIPELINE_LENGTH; libcurl: CURLMOPT_MAX_PIPELINE_LENGTH

CURLMOPT_MAX_TOTAL_CONNECTIONS
Тип самой константы: int

int: общий предел открытых соединений multi; 0 по умолчанию не ограничивает. Лишние передачи ожидают, а их таймауты продолжают отсчитываться. Multiplexing позволяет нескольким передачам занять одно соединение. Уменьшение предела не отменяет активные передачи.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 7.0.7 и libcurl 7.30.0 Native API: libcurl 7.30.0.

PHP: CURLMOPT_MAX_TOTAL_CONNECTIONS; libcurl: CURLMOPT_MAX_TOTAL_CONNECTIONS

CURLMOPT_PIPELINING
Тип самой константы: int

int-маска CURLPIPE_*. Исторически 0/1 отключали/включали HTTP/1 pipelining, с 7.43.0 бит 2 разрешает multiplexing, 3 объединял оба режима. С 7.62.0 HTTP/1 pipelining удалён; актуальный default — CURLPIPE_MULTIPLEX. Не передавать true, если требуется именно multiplexing: true становится 1.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с libcurl 7.16.0. Native API: libcurl 7.16.0.

PHP: CURLMOPT_PIPELINING; libcurl: CURLMOPT_PIPELINING

CURLMOPT_PUSHFUNCTION
Тип самой константы: int

callable(CurlHandle $parent, CurlHandle $pushed, array $headers): int в PHP 8+: parent — исходный запрос, pushed — новый push handle, headers — заголовки push promise. Вернуть CURL_PUSH_OK или CURL_PUSH_DENY. В старой PHP-документации параметры названы resource: до PHP 8 handles действительно были ресурсами. Default — callback отсутствует, push отвергается.

Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы.

Версии: Доступно с PHP 7.1.0 и libcurl 7.44.0 Constants Description libcurl protocol constants Native API: libcurl 7.44.0.

PHP: CURLMOPT_PUSHFUNCTION; libcurl: CURLMOPT_PUSHFUNCTION

CURLMSG_DONE
Тип самой константы: int

Тип сообщения «передача завершилась». Сообщение содержит easy handle и отдельный result CURLE_*; DONE сам по себе не доказывает успех ответа.

Значение/результат: int: тип сообщения из curl_multi_info_read.

PHP: CURLMSG_DONE; libcurl: curl_multi_info_read

CURLM_ADDED_ALREADY
Тип самой константы: int

Попытка второй раз добавить уже добавленный easy handle. Не считать это успешной регистрацией нового запроса.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.32.1.

PHP: CURLM_ADDED_ALREADY; libcurl: libcurl-errors

CURLM_BAD_EASY_HANDLE
Тип самой константы: int

Некорректный easy handle для multi-операции. На границе PHP объект неправильного класса обычно отсекается TypeError ещё до libcurl.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.9.6.

PHP: CURLM_BAD_EASY_HANDLE; libcurl: libcurl-errors

CURLM_BAD_HANDLE
Тип самой константы: int

Некорректный multi handle в libcurl. PHP дополнительно проверяет тип объекта на входе функции.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.9.6.

PHP: CURLM_BAD_HANDLE; libcurl: libcurl-errors

CURLM_CALL_MULTI_PERFORM
Тип самой константы: int

Исторический запрос немедленно повторить обработку multi. Начиная с libcurl 7.20.0 этот статус не используется; не строить современный цикл вокруг ожидания этого значения.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.9.6.

PHP: CURLM_CALL_MULTI_PERFORM; libcurl: libcurl-errors

CURLM_INTERNAL_ERROR
Тип самой константы: int

Внутренняя ошибка механизма multi; это не HTTP-код отдельного ответа.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.9.6.

PHP: CURLM_INTERNAL_ERROR; libcurl: libcurl-errors

CURLM_OK
Тип самой константы: int

Multi-операция выполнена без ошибки на уровне multi. Отдельные запросы всё ещё могут завершиться с CURLE_*; читать result через curl_multi_info_read.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.9.6.

PHP: CURLM_OK; libcurl: libcurl-errors

CURLM_OUT_OF_MEMORY
Тип самой константы: int

Не хватило памяти для обработки multi. Не повторять бесконечно ту же нагрузку.

Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи.

Версии: Доступно с libcurl 7.9.6.

PHP: CURLM_OUT_OF_MEMORY; libcurl: libcurl-errors

CURLPIPE_HTTP1
Тип самой константы: int

Исторический бит HTTP/1.1 pipelining: несколько запросов по соединению до получения ответов. С libcurl 7.62.0 pipelining удалён и бит не действует; это не HTTP/2 multiplexing.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.43.0.

PHP: CURLPIPE_HTTP1; libcurl: CURLMOPT_PIPELINING

CURLPIPE_MULTIPLEX
Тип самой константы: int

Разрешить одновременные HTTP/2 или HTTP/3 streams в соединении при поддержке протокола. Это разрешение, а не обещание объединения любых запросов.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.43.0.

PHP: CURLPIPE_MULTIPLEX; libcurl: CURLMOPT_PIPELINING

CURLPIPE_NOTHING
Тип самой константы: int

Нулевая маска: не запрашивать multiplexing. Последовательное повторное использование соединения этим не запрещается.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.43.0.

PHP: CURLPIPE_NOTHING; libcurl: CURLMOPT_PIPELINING

CURL_PUSH_DENY
Тип самой константы: int

Ответ callback: отвергнуть предложенный сервером push. Без callback libcurl отвергает push по умолчанию.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.1.0 и libcurl 7.44.0

PHP: CURL_PUSH_DENY; libcurl: CURLMOPT_PUSHFUNCTION

CURL_PUSH_OK
Тип самой константы: int

Ответ callback: принять предложенный HTTP/2 push handle. Не означает, что передача уже завершена успешно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.1.0 и libcurl 7.44.0

PHP: CURL_PUSH_OK; libcurl: CURLMOPT_PUSHFUNCTION

Share: какие данные можно разделить

Share объединяет выбранные кэши, а не запускает конкурентные запросы. Один multi уже разделяет некоторые данные своих handles. Не передавайте cookie-состояние разных пользователей в общее хранилище. Обычный CurlShareHandle и persistent share PHP 8.5 имеют отдельные границы; отдельная константа lock-data не обещает потокобезопасности во всех native сценариях.

Разделить только DNS cache
  1. Создать share
  2. CURLSHOPT_SHARE получает CURL_LOCK_DATA_DNS
  3. CURLOPT_SHARE присоединяет нужные easy handles
  4. Cookie и TLS session остаются отдельными, если их не включили
  5. Менять sharing можно между активными передачами

Практика присоединения хранилища: curl_share_setopt; настройка easy handle — curl_setopt.

КонстантаНазначение, договор и границы
CURLOPT_SHARE
Тип самой константы: int

Присоединяет общее хранилище выбранных curl_share_setopt видов данных. PHP 8.5 также принимает persistent share. Типы, не включённые в share, остаются обычными локальными. В native NULL отсоединяет, но PHP 8.5.11 при null просто пропускает case: это не detach. Не менять sharing во время активной передачи; thread-safety native не превращает обычный PHP-объект в универсально безопасный общий ресурс.

Значение/результат: CurlShareHandle|CurlSharePersistentHandle.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.10. Native API: libcurl 7.10.

PHP: CURLOPT_SHARE; libcurl: CURLOPT_SHARE

CURLSHOPT_NONE
Тип самой константы: int

Нулевой служебный элемент перечисления share-настроек. Не является командой «отключить всё»: используйте UNSHARE с конкретным видом данных.

Значение/результат: ключ curl_share_setopt; значение одного CURL_LOCK_DATA_* (кроме служебного NONE).

Версии: Доступно с libcurl 7.10.3. Native API CURLSHOPT_SHARE: libcurl 7.10.3.

PHP: CURLSHOPT_NONE; libcurl: CURLSHOPT_SHARE

CURLSHOPT_SHARE
Тип самой константы: int

Ключ curl_share_setopt: значением передать один CURL_LOCK_DATA_* для включения общего хранилища. Для нескольких видов данных вызвать несколько раз. Менять набор только между передачами, пока share не используется; само включение COOKIE не запускает cookie engine easy handle.

Значение/результат: ключ curl_share_setopt; значение одного CURL_LOCK_DATA_* (кроме служебного NONE).

Версии: Доступно с libcurl 7.10.3. Native API: libcurl 7.10.3.

PHP: CURLSHOPT_SHARE; libcurl: CURLSHOPT_SHARE

CURLSHOPT_UNSHARE
Тип самой константы: int

Ключ curl_share_setopt: значением передать один CURL_LOCK_DATA_* для прекращения разделения этого вида данных. Вызывать между передачами, когда share не используется. Это не CURLOPT_SHARE=null: в текущем PHP null у той настройки не выполняет detach.

Значение/результат: ключ curl_share_setopt; значение одного CURL_LOCK_DATA_* (кроме служебного NONE).

Версии: Доступно с libcurl 7.10.3. Native API: libcurl 7.10.3.

PHP: CURLSHOPT_UNSHARE; libcurl: CURLSHOPT_UNSHARE

CURL_LOCK_DATA_CONNECT
Тип самой константы: int

Общий кеш соединений; один multi уже объединяет его для своих handles. Совместное использование соединений между одновременно работающими native threads не поддерживается. HTTP/2/3 multiplexing требует одного соответствующего multi/easy контекста; лимиты multi учитываются и для shared cache.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.10.3.

PHP: CURL_LOCK_DATA_CONNECT; libcurl: CURLSHOPT_SHARE

CURL_LOCK_DATA_COOKIE
Тип самой константы: int

Общие cookies easy handles. Cookie engine включается отдельно, например COOKIEFILE=""; настройка share сама его не включает. Общие cookies между одновременно работающими native threads не поддерживаются.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.3.

PHP: CURL_LOCK_DATA_COOKIE; libcurl: CURLSHOPT_SHARE

CURL_LOCK_DATA_DNS
Тип самой константы: int

Общий кеш результатов DNS. Handles одного multi и так используют общий DNS cache; отдельный share нужен при другой организации handles.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.3.

PHP: CURL_LOCK_DATA_DNS; libcurl: CURLSHOPT_SHARE

CURL_LOCK_DATA_PSL
Тип самой константы: int

Общая Public Suffix List — список публичных суффиксов для корректных cookie boundaries. Это избегает независимых обновлений кеша; внутри одного multi PSL уже разделяется.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0.

PHP: CURL_LOCK_DATA_PSL; libcurl: CURLSHOPT_SHARE

CURL_LOCK_DATA_SSL_SESSION
Тип самой константы: int

Общий кеш TLS sessions для сокращения повторного handshake. Один handle и handles одного multi уже могут повторно использовать sessions. Это не отключение проверки сертификатов.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.10.3.

PHP: CURL_LOCK_DATA_SSL_SESSION; libcurl: CURLSHOPT_SHARE

Локальные прикладные метки

PRIVATE помогает сопоставить завершившийся handle с заказом/заданием. Это локальный контекст приложения, не опция аутентификации и не место, которое удалённый сервер сможет прочитать.

При нескольких запросах полезно помнить, к какой задаче относится handle. PRIVATE хранит прикладную метку локально; она не превращается в HTTP-заголовок и не отправляется серверу.

Локальная метка заказа
  1. Массив order=42, attempt=1
  2. CURLOPT_PRIVATE сохраняет значение
  3. CURLINFO_PRIVATE возвращает его приложению
  4. Сеть не участвует

Этот вариант. PHP сохраняет mixed-значение, хотя native libcurl API говорит о void*. Без явно заданного PRIVATE PHP возвращает false. Для объектов действуют обычные правила PHP object handle; не считайте это копией всего графа объектов.

Связать клиент с локальным заданиемСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
$context = ['order' => 42, 'attempt' => 1];
curl_setopt($handle, CURLOPT_PRIVATE, $context);
$saved = curl_getinfo($handle, CURLINFO_PRIVATE);
if (!is_array($saved)) throw new RuntimeException('Контекст потерян');
echo 'Заказ ', $saved['order'], ', попытка ', $saved['attempt'], "\n";
Ожидаемый результат
Заказ 42, попытка 1
КонстантаНазначение, договор и границы
CURLOPT_PRIVATE
Тип самой константы: int

Локальное значение PHP, связанное с handle: ключ заказа, массив контекста или объект. Получается через CURLINFO_PRIVATE; libcurl не отправляет его в сеть и не интерпретирует. PHP сохраняет zval, а не native string pointer. Объект остаётся тем же объектом, что важно для изменяемого контекста.

Значение/результат: mixed.

По умолчанию: не задан; getinfo тогдаfalse.

Версии: Доступно с libcurl 7.10.3. Native API: libcurl 7.10.3.

PHP: CURLOPT_PRIVATE; libcurl: CURLOPT_PRIVATE

Результат, размеры и тайминги CURLINFO

getinfo читает сведения последней передачи. Часть полей остаётся от предыдущего запроса при reuse; читайте сразу после нужного exec и сохраняйте рядом с заданием. Не принимайте отсутствие информации за успешную проверку. native C-типы отличаются от PHP int/float/string/array и их диапазонов.

Отказ передачи и код HTTP-ответа — разные уровни. file:// вообще не имеет HTTP-статуса, поэтому успешное чтение файла не должно выдавать 200. На нём удобно увидеть разницу между CURLINFO_* и CURLE_* без сети.

Три независимых результата
  1. curl_exec возвращает содержимое файла
  2. curl_errno = CURLE_OK: передача успешна
  3. CURLINFO_RESPONSE_CODE = 0: HTTP-ответа не было
  4. Длина тела: байты фактически полученной строки

Этот вариант. CURLE_OK равен 0. Для HTTP API дополнительно проверяйте ожидаемый диапазон статусов и формат body. curl_exec не возвращает false только из-за HTTP 404, если политика FAILONERROR не включена. Отсутствующее Content-Length не означает пустой ответ.

Отделить транспортный успех от HTTP-статусаСамостоятельный пример
<?php
declare(strict_types=1);

$path = realpath(__DIR__ . '/stock.csv');
if ($path === false) throw new RuntimeException('Нет файла');
$url = 'file:///' . str_replace(['\\', ' '], ['/', '%20'], ltrim($path, '/'));
$handle = curl_init($url);
if ($handle === false) throw new RuntimeException('Нет клиента');
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($handle);
if (!is_string($body)) throw new RuntimeException(curl_error($handle));
echo 'Ошибка передачи: ', curl_errno($handle), "\n";
echo 'Код HTTP: ', curl_getinfo($handle, CURLINFO_RESPONSE_CODE), "\n";
echo 'Получено байтов: ', strlen($body), "\n";
Ожидаемый результат
Ошибка передачи: 0
Код HTTP: 0
Получено байтов: 6

У таймингов единицы различаются: исторические значения — float секунд, *_TIME_T — целочисленные микросекунды. Многие значения накоплены от начала операции, поэтому их нельзя просто сложить. Повторное использование соединения и redirect меняют смысл отдельных фаз. У размеров различайте заявленный Content-Length, фактические байты и скорость в байтах/с. Большие native curl_off_t счётчики требуют учёта разрядности PHP и конкретного преобразования платформы.

КонстантаНазначение, договор и границы
CURLINFO_APPCONNECT_TIME
Тип самой константы: int

От начала до завершения TLS/SSH handshake. При HTTP multiplexing PRETRANSFER может наступить позже из-за очереди stream. Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.19.0.

PHP: CURLINFO_APPCONNECT_TIME; libcurl: CURLINFO_APPCONNECT_TIME

CURLINFO_APPCONNECT_TIME_T
Тип самой константы: int

От начала до завершения TLS/SSH handshake. При HTTP multiplexing PRETRANSFER может наступить позже из-за очереди stream. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_APPCONNECT_TIME_T; libcurl: CURLINFO_APPCONNECT_TIME_T

CURLINFO_CAINFO
Тип самой константы: int

Встроенный default путь к одному файлу CA, а не гарантированно фактическое значение после пользовательского CURLOPT_CAINFO. Может отсутствовать. В MultiSSL сборке путь может существовать для другого backend, который сейчас не активен.

Значение/результат: string|false.

Версии: Доступно с PHP 8.3.0 и libcurl 7.84.0 Native API: libcurl 7.84.0.

PHP: CURLINFO_CAINFO; libcurl: CURLINFO_CAINFO

CURLINFO_CAPATH
Тип самой константы: int

Встроенный default путь к каталогу CA, а не обязательно пользовательская настройка CAPATH. Может отсутствовать или относиться к неактивному TLS backend.

Значение/результат: string|false.

Версии: Доступно с PHP 8.3.0 и libcurl 7.84.0 Native API: libcurl 7.84.0.

PHP: CURLINFO_CAPATH; libcurl: CURLINFO_CAPATH

CURLINFO_CERTINFO
Тип самой константы: int

Информация о цепочке сертификатов сервера, если до передачи включён CURLOPT_CERTINFO. PHP возвращает массив сведений о сертификатах; набор полей зависит от backend и сертификата. Это не самостоятельная проверка доверия.

Значение/результат: array|false.

Версии: Native API: libcurl 7.19.1.

PHP: CURLINFO_CERTINFO; libcurl: CURLINFO_CERTINFO

CURLINFO_CONDITION_UNMET
Тип самой константы: int

1 означает, что временное/условное требование не выполнено, поэтому тело могло отсутствовать; 0 — такой причины не отмечено. Значение 1 возможно и при HTTP 304 после собственного условного заголовка.

Значение/результат: int|false.

Версии: Native API: libcurl 7.19.4.

PHP: CURLINFO_CONDITION_UNMET; libcurl: CURLINFO_CONDITION_UNMET

CURLINFO_CONNECT_TIME
Тип самой константы: int

От начала до установления соединения с сервером или proxy; DNS уже входит в этот интервал. Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.4.1.

PHP: CURLINFO_CONNECT_TIME; libcurl: CURLINFO_CONNECT_TIME

CURLINFO_CONNECT_TIME_T
Тип самой константы: int

От начала до установления соединения с сервером или proxy; DNS уже входит в этот интервал. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_CONNECT_TIME_T; libcurl: CURLINFO_CONNECT_TIME_T

CURLINFO_CONN_ID
Тип самой константы: int

Идентификатор последнего соединения, -1 если оно не использовалось. Уникален в одном кеше соединений, например одном multi, а не глобально между процессами.

Значение/результат: int|false.

Версии: Доступно с PHP 8.5.0 и libcurl 8.2.0. Native API: libcurl 8.2.0.

PHP: CURLINFO_CONN_ID; libcurl: CURLINFO_CONN_ID

CURLINFO_CONTENT_LENGTH_DOWNLOAD
Тип самой константы: int

Ожидаемая длина ответа из Content-Length в байтах; -1 означает неизвестный размер. Не гарантирует, что сервер действительно передаст столько байтов. Native double API устарел с 7.55.0; вариант _T использует целочисленный native счётчик.

Значение/результат: float|false.

Версии: Устарело с libcurl 7.55.0. Native API: libcurl 7.6.1.

PHP: CURLINFO_CONTENT_LENGTH_DOWNLOAD; libcurl: CURLINFO_CONTENT_LENGTH_DOWNLOAD

CURLINFO_CONTENT_LENGTH_DOWNLOAD_T
Тип самой константы: int

Ожидаемая длина ответа из Content-Length в байтах; -1 означает неизвестный размер. Не гарантирует, что сервер действительно передаст столько байтов. В native это curl_off_t; границы конкретного PHP/platform преобразования всё равно проверять для очень больших значений.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.55.0 Native API: libcurl 7.55.0.

PHP: CURLINFO_CONTENT_LENGTH_DOWNLOAD_T; libcurl: CURLINFO_CONTENT_LENGTH_DOWNLOAD_T

CURLINFO_CONTENT_LENGTH_UPLOAD
Тип самой константы: int

Заданный до начала ожидаемый размер отправки в байтах; -1 означает неизвестный. Фактический результат смотреть в SIZE_UPLOAD_T. Native double API устарел с 7.55.0; вариант _T использует целочисленный native счётчик.

Значение/результат: float|false.

Версии: Устарело с libcurl 7.55.0. Native API: libcurl 7.6.1.

PHP: CURLINFO_CONTENT_LENGTH_UPLOAD; libcurl: CURLINFO_CONTENT_LENGTH_UPLOAD

CURLINFO_CONTENT_LENGTH_UPLOAD_T
Тип самой константы: int

Заданный до начала ожидаемый размер отправки в байтах; -1 означает неизвестный. Фактический результат смотреть в SIZE_UPLOAD_T. В native это curl_off_t; границы конкретного PHP/platform преобразования всё равно проверять для очень больших значений.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.55.0 Native API: libcurl 7.55.0.

PHP: CURLINFO_CONTENT_LENGTH_UPLOAD_T; libcurl: CURLINFO_CONTENT_LENGTH_UPLOAD_T

CURLINFO_CONTENT_TYPE
Тип самой константы: int

Значение Content-Type ответа. Native-документация пишет NULL при отсутствии, но одиночный PHP curl_getinfo на PHP 8.5.11 возвращает false; в полном массиве поле content_type может быть null. Это заявление сервера о формате, не доказательство валидного JSON или безопасного файла.

Значение/результат: string|false.

Версии: Native API: libcurl 7.9.4.

PHP: CURLINFO_CONTENT_TYPE; libcurl: CURLINFO_CONTENT_TYPE

CURLINFO_COOKIELIST
Тип самой константы: int

Все известные libcurl cookies, включая просроченные; без cookies — пустой массив. Cookies, импортированные строкой Set-Cookie без domain, здесь не экспортируются. Содержимое конфиденциально.

Значение/результат: array|false.

Версии: Native API: libcurl 7.14.1.

PHP: CURLINFO_COOKIELIST; libcurl: CURLINFO_COOKIELIST

CURLINFO_EFFECTIVE_METHOD
Тип самой константы: int

Фактически использованный последний HTTP-метод: после redirect он может отличаться от исходного POST/GET.

Значение/результат: string|false.

Версии: Native API: libcurl 7.72.0.

PHP: CURLINFO_EFFECTIVE_METHOD; libcurl: CURLINFO_EFFECTIVE_METHOD

CURLINFO_EFFECTIVE_URL
Тип самой константы: int

Последний эффективный URL, в том числе после redirect. Значение может быть доступно уже после настройки URL, поэтому само его наличие не доказывает исполнение запроса.

Значение/результат: string|false.

Версии: Native API: libcurl 7.4.

PHP: CURLINFO_EFFECTIVE_URL; libcurl: CURLINFO_EFFECTIVE_URL

CURLINFO_FILETIME
Тип самой константы: int

Unix timestamp удалённого файла в секундах UTC; -1 — неизвестно. До запроса требуется CURLOPT_FILETIME=true. Native long ограничен 32 битами на Windows; _T расширяет native API, но PHP-преобразование результата тоже требует проверки.

Значение/результат: int|false.

Версии: Native API: libcurl 7.5.

PHP: CURLINFO_FILETIME; libcurl: CURLINFO_FILETIME

CURLINFO_FILETIME_T
Тип самой константы: int

Тот же Unix timestamp или -1, через native curl_off_t вместо long; нужна предварительная CURLOPT_FILETIME. На PHP 8.5.11 одиночный getinfo source всё ещё приводит _T через C long: на Windows нельзя обещать сохранение всего 64-битного диапазона без отдельной проверки.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.59.0 Native API: libcurl 7.59.0.

PHP: CURLINFO_FILETIME_T; libcurl: CURLINFO_FILETIME_T

CURLINFO_FTP_ENTRY_PATH
Тип самой константы: int

Начальный каталог после входа на FTP или SFTP сервер; не обязательно каталог запрошенного файла.

Значение/результат: string|false.

Версии: Native API: libcurl 7.15.4.

PHP: CURLINFO_FTP_ENTRY_PATH; libcurl: CURLINFO_FTP_ENTRY_PATH

CURLINFO_HEADER_SIZE
Тип самой константы: int

Суммарная длина полученных заголовков в байтах, представленных как HTTP/1. Включает заголовки CONNECT, даже скрытые SUPPRESS_CONNECT_HEADERS. Для HTTP/2/3 это не число физических байтов сжатых заголовков в сети.

Значение/результат: int|false.

Версии: Native API: libcurl 7.4.1.

PHP: CURLINFO_HEADER_SIZE; libcurl: CURLINFO_HEADER_SIZE

CURLINFO_HTTPAUTH_AVAIL
Тип самой константы: int

Маска CURLAUTH_* способов входа, предложенных предыдущим ответом сервера; это не выбранный способ.

Значение/результат: int|false.

Версии: Native API: libcurl 7.10.8.

PHP: CURLINFO_HTTPAUTH_AVAIL; libcurl: CURLINFO_HTTPAUTH_AVAIL

CURLINFO_HTTPAUTH_USED
Тип самой константы: int

Способ HTTP-аутентификации предыдущего запроса: 0 либо один установленный бит CURLAUTH_*. Отличается от списка AVAIL.

Значение/результат: int|false.

Версии: Доступно с PHP 8.5.0 и libcurl 8.12.0. Native API: libcurl 8.12.0.

PHP: CURLINFO_HTTPAUTH_USED; libcurl: CURLINFO_HTTPAUTH_USED

CURLINFO_HTTP_CODE
Тип самой константы: int

Исторический alias RESPONSE_CODE с libcurl 7.10.8. Возвращается протокольный статус последнего ответа, 0 если его не было; не CURLcode.

Значение/результат: int|false.

Версии: Native API CURLINFO_RESPONSE_CODE: libcurl 7.10.8.

PHP: CURLINFO_HTTP_CODE; libcurl: CURLINFO_RESPONSE_CODE

CURLINFO_HTTP_CONNECTCODE
Тип самой константы: int

Последний HTTP-статус ответа proxy на CONNECT, 0 при отсутствии. Не путать со статусом ответа целевого приложения.

Значение/результат: int|false.

Версии: Native API: libcurl 7.10.7.

PHP: CURLINFO_HTTP_CONNECTCODE; libcurl: CURLINFO_HTTP_CONNECTCODE

CURLINFO_HTTP_VERSION
Тип самой константы: int

Фактическая версия последней HTTP-передачи: CURL_HTTP_VERSION_1_0, 1_1, 2_0, 3 либо 0 если не определена. Не число 2/3 для произвольного сравнения.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.50.0 Native API: libcurl 7.50.0.

PHP: CURLINFO_HTTP_VERSION; libcurl: CURLINFO_HTTP_VERSION

CURLINFO_LASTONE
Тип самой константы: int

Последний служебный элемент native enum CURLINFO. Не информационное поле и не обещание непрерывного диапазона допустимых PHP getinfo ключей.

Значение/результат: int: служебная граница.

PHP: CURLINFO_LASTONE

CURLINFO_LOCAL_IP
Тип самой константы: int

IP локального конца последнего соединения; строка может содержать IPv6. Это не публичный IP приложения за NAT.

Значение/результат: string|false.

Версии: Native API: libcurl 7.21.0.

PHP: CURLINFO_LOCAL_IP; libcurl: CURLINFO_LOCAL_IP

CURLINFO_LOCAL_PORT
Тип самой константы: int

Локальный порт последнего TCP/UDP соединения; QUIC использует UDP. В актуальном libcurl -1, если соединения/портов не было.

Значение/результат: int|false.

Версии: Native API: libcurl 7.21.0.

PHP: CURLINFO_LOCAL_PORT; libcurl: CURLINFO_LOCAL_PORT

CURLINFO_NAMELOOKUP_TIME
Тип самой константы: int

От начала до завершения разрешения имени. Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.4.1.

PHP: CURLINFO_NAMELOOKUP_TIME; libcurl: CURLINFO_NAMELOOKUP_TIME

CURLINFO_NAMELOOKUP_TIME_T
Тип самой константы: int

От начала до завершения разрешения имени. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_NAMELOOKUP_TIME_T; libcurl: CURLINFO_NAMELOOKUP_TIME_T

CURLINFO_NUM_CONNECTS
Тип самой константы: int

Число успешно созданных новых соединений в предыдущей передаче. Повторное использование существующего соединения не увеличивает счётчик.

Значение/результат: int|false.

Версии: Native API: libcurl 7.12.3.

PHP: CURLINFO_NUM_CONNECTS; libcurl: CURLINFO_NUM_CONNECTS

CURLINFO_OS_ERRNO
Тип самой константы: int

Системный errno сетевого сбоя: значения зависят от ОС. С libcurl 8.8.0 сохранённый errno очищается перед передачей; в старых версиях мог остаться от предыдущего запроса того же handle. Не трактовать положительный errno без контекста ошибки.

Значение/результат: int|false.

Версии: Native API: libcurl 7.12.2.

PHP: CURLINFO_OS_ERRNO; libcurl: CURLINFO_OS_ERRNO

CURLINFO_POSTTRANSFER_TIME_T
Тип самой константы: int

От начала до отправки последнего байта, в микросекундах. При переходах интервалы суммируются; это не время получения полного ответа.

Значение/результат: int|false.

Версии: Доступно с PHP 8.4.0 и libcurl 8.10.0 Constants Description curl_multi_setopt() Native API: libcurl 8.10.0.

PHP: CURLINFO_POSTTRANSFER_TIME_T; libcurl: CURLINFO_POSTTRANSFER_TIME_T

CURLINFO_PRETRANSFER_TIME
Тип самой константы: int

От начала до готовности начать передачу: включает необходимые протокольные команды и согласования. Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.4.1.

PHP: CURLINFO_PRETRANSFER_TIME; libcurl: CURLINFO_PRETRANSFER_TIME

CURLINFO_PRETRANSFER_TIME_T
Тип самой константы: int

От начала до готовности начать передачу: включает необходимые протокольные команды и согласования. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_PRETRANSFER_TIME_T; libcurl: CURLINFO_PRETRANSFER_TIME_T

CURLINFO_PRIMARY_IP
Тип самой константы: int

IP фактического удалённого конца последнего соединения, IPv4 или IPv6. При proxy это может быть адрес proxy, а не origin.

Значение/результат: string|false.

Версии: Native API: libcurl 7.19.0.

PHP: CURLINFO_PRIMARY_IP; libcurl: CURLINFO_PRIMARY_IP

CURLINFO_PRIMARY_PORT
Тип самой константы: int

Порт фактического удалённого TCP/UDP соединения; при proxy — порт proxy. В актуальном libcurl -1 при отсутствии соединения или протокола с портами.

Значение/результат: int|false.

Версии: Native API: libcurl 7.21.0.

PHP: CURLINFO_PRIMARY_PORT; libcurl: CURLINFO_PRIMARY_PORT

CURLINFO_PRIVATE
Тип самой константы: int

В PHP возвращает сохранённое значение CURLOPT_PRIVATE, включая массив/объект; оно не отправляется серверу. Если значение не задавали — false. Заданное false и отсутствие значения этим одним результатом не различаются.

Значение/результат: mixed.

Версии: Native API: libcurl 7.10.3.

PHP: CURLINFO_PRIVATE; libcurl: CURLINFO_PRIVATE

CURLINFO_PROTOCOL
Тип самой константы: int

Исторический CURLPROTO_* протокол последней передачи, не только HTTP. Native API устарел с 7.85.0 и не представляет все современные схемы; использовать SCHEME.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0. Устарело с libcurl 7.85.0. Native API: libcurl 7.52.0.

PHP: CURLINFO_PROTOCOL; libcurl: CURLINFO_PROTOCOL

CURLINFO_PROXYAUTH_AVAIL
Тип самой константы: int

Маска CURLAUTH_* способов аутентификации, предложенных HTTP proxy, отдельно от HTTPAUTH_AVAIL сервера.

Значение/результат: int|false.

Версии: Native API: libcurl 7.10.8.

PHP: CURLINFO_PROXYAUTH_AVAIL; libcurl: CURLINFO_PROXYAUTH_AVAIL

CURLINFO_PROXYAUTH_USED
Тип самой константы: int

Способ входа, реально применённый к HTTP proxy: 0 либо один бит CURLAUTH_*.

Значение/результат: int|false.

Версии: Доступно с PHP 8.5.0 и libcurl 8.12.0. Native API: libcurl 8.12.0.

PHP: CURLINFO_PROXYAUTH_USED; libcurl: CURLINFO_PROXYAUTH_USED

CURLINFO_PROXY_ERROR
Тип самой константы: int

Подробность SOCKS-отказа после CURLE_PROXY: один CURLPX_*. CURLPX_OK=0 возвращается и когда подробный ответ недоступен; не означает независимого подтверждения успеха.

Значение/результат: int|false.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 Native API: libcurl 7.73.0.

PHP: CURLINFO_PROXY_ERROR; libcurl: CURLINFO_PROXY_ERROR

CURLINFO_PROXY_SSL_VERIFYRESULT
Тип самой константы: int

Результат запрошенной проверки сертификата HTTPS proxy: 0 — положительный результат, ненулевой — ошибка backend. При выключенной проверке 0 не доказывает доверие.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0 Native API: libcurl 7.52.0.

PHP: CURLINFO_PROXY_SSL_VERIFYRESULT; libcurl: CURLINFO_PROXY_SSL_VERIFYRESULT

CURLINFO_QUEUE_TIME_T
Тип самой константы: int

Микросекунды ожидания во внутренней очереди перед началом передачи, например из-за MAX_TOTAL_CONNECTIONS. Помогает отличить очередь клиента от медленного сервера.

Значение/результат: int|false.

Версии: Доступно с PHP 8.5.0 и libcurl 8.6.0. Native API: libcurl 8.6.0.

PHP: CURLINFO_QUEUE_TIME_T; libcurl: CURLINFO_QUEUE_TIME_T

CURLINFO_REDIRECT_COUNT
Тип самой константы: int

Количество фактически выполненных redirect. Сам по себе полученный Location, которому не следовали, сюда не добавляется.

Значение/результат: int|false.

Версии: Native API: libcurl 7.9.7.

PHP: CURLINFO_REDIRECT_COUNT; libcurl: CURLINFO_REDIRECT_COUNT

CURLINFO_REDIRECT_TIME
Тип самой константы: int

Суммарное время всех выполненных переходов до начала последней транзакции: DNS, соединение, подготовка и обмен на промежуточных шагах. Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.9.7.

PHP: CURLINFO_REDIRECT_TIME; libcurl: CURLINFO_REDIRECT_TIME

CURLINFO_REDIRECT_TIME_T
Тип самой константы: int

Суммарное время всех выполненных переходов до начала последней транзакции: DNS, соединение, подготовка и обмен на промежуточных шагах. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_REDIRECT_TIME_T; libcurl: CURLINFO_REDIRECT_TIME_T

CURLINFO_REDIRECT_URL
Тип самой константы: int

Адрес следующего перехода, которому libcurl не последовал. Полезен при FOLLOWLOCATION=false; также заполняется, когда переход остановлен MAXREDIRS. При успешно пройденной цепочке последнюю цель читать в EFFECTIVE_URL.

Значение/результат: string|false.

Версии: Native API: libcurl 7.18.2.

PHP: CURLINFO_REDIRECT_URL; libcurl: CURLINFO_REDIRECT_URL

CURLINFO_REFERER
Тип самой константы: int

Referer, использованный в последнем запросе. При AUTOREFERER может отличаться от первоначальной настройки; данные URL могут быть конфиденциальны.

Значение/результат: string|false.

Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0 Native API: libcurl 7.76.0.

PHP: CURLINFO_REFERER; libcurl: CURLINFO_REFERER

CURLINFO_REQUEST_SIZE
Тип самой константы: int

Общий размер выданных HTTP-запросов в байтах; при FOLLOWLOCATION может относиться к нескольким запросам, а не только одному.

Значение/результат: int|false.

Версии: Native API: libcurl 7.4.1.

PHP: CURLINFO_REQUEST_SIZE; libcurl: CURLINFO_REQUEST_SIZE

CURLINFO_RESPONSE_CODE
Тип самой константы: int

Последний статус HTTP, FTP, SMTP либо LDAP (OpenLDAP). 0 означает отсутствие статуса. Ответ proxy CONNECT читается через HTTP_CONNECTCODE.

Значение/результат: int|false.

Версии: Доступно с libcurl 7.10.8 Native API: libcurl 7.10.8.

PHP: CURLINFO_RESPONSE_CODE; libcurl: CURLINFO_RESPONSE_CODE

CURLINFO_RETRY_AFTER
Тип самой константы: int

Число секунд ожидания из Retry-After, даже если заголовок содержал дату. 0 — нет пригодного заголовка; до libcurl 8.12.0 прошлые даты могли дать отрицательное число, сейчас прижимаются к 0. Приложение задаёт верхний предел ожидания и политику повторов, а не безусловный sleep.

Значение/результат: int|false.

Версии: Доступно с PHP 8.2.0 и libcurl 7.66.0 Native API: libcurl 7.66.0.

PHP: CURLINFO_RETRY_AFTER; libcurl: CURLINFO_RETRY_AFTER

CURLINFO_RTSP_CLIENT_CSEQ
Тип самой константы: int

Следующий клиентский RTSP CSeq — номер команды, который ожидается использовать.

Значение/результат: int|false.

Версии: Native API: libcurl 7.20.0.

PHP: CURLINFO_RTSP_CLIENT_CSEQ; libcurl: CURLINFO_RTSP_CLIENT_CSEQ

CURLINFO_RTSP_CSEQ_RECV
Тип самой константы: int

Последний полученный от RTSP-сервера CSeq для диагностики несоответствия номеров.

Значение/результат: int|false.

Версии: Native API: libcurl 7.20.0.

PHP: CURLINFO_RTSP_CSEQ_RECV; libcurl: CURLINFO_RTSP_CSEQ_RECV

CURLINFO_RTSP_SERVER_CSEQ
Тип самой константы: int

Следующий ожидаемый серверный CSeq; native libcurl не реализует прослушивание инициированных сервером запросов. Сохранить перед переносом управления RTSP-сессией на другое соединение.

Значение/результат: int|false.

Версии: Native API: libcurl 7.20.0.

PHP: CURLINFO_RTSP_SERVER_CSEQ; libcurl: CURLINFO_RTSP_SERVER_CSEQ

CURLINFO_RTSP_SESSION_ID
Тип самой константы: int

Последний RTSP Session ID. Сохранить перед закрытием соединения, если приложение продолжит ту же сессию на другом.

Значение/результат: string|false.

Версии: Native API: libcurl 7.20.0.

PHP: CURLINFO_RTSP_SESSION_ID; libcurl: CURLINFO_RTSP_SESSION_ID

CURLINFO_SCHEME
Тип самой константы: int

Схема последнего URL. Native API не обещает регистр букв: сравнивать без учёта регистра. Это более полный преемник PROTOCOL.

Значение/результат: string|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0 Native API: libcurl 7.52.0.

PHP: CURLINFO_SCHEME; libcurl: CURLINFO_SCHEME

CURLINFO_SIZE_DOWNLOAD
Тип самой константы: int

Фактически полученные payload/body байты последней передачи, без заголовков и metadata; счётчик сбрасывается для следующей передачи. Native double API устарел с 7.55.0; вариант _T использует целочисленный native счётчик.

Значение/результат: float|false.

Версии: Устарело с libcurl 7.55.0. Native API: libcurl 7.4.1.

PHP: CURLINFO_SIZE_DOWNLOAD; libcurl: CURLINFO_SIZE_DOWNLOAD

CURLINFO_SIZE_DOWNLOAD_T
Тип самой константы: int

Фактически полученные payload/body байты последней передачи, без заголовков и metadata; счётчик сбрасывается для следующей передачи. В native это curl_off_t; границы конкретного PHP/platform преобразования всё равно проверять для очень больших значений.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.50.0 Native API: libcurl 7.55.0.

PHP: CURLINFO_SIZE_DOWNLOAD_T; libcurl: CURLINFO_SIZE_DOWNLOAD_T

CURLINFO_SIZE_UPLOAD
Тип самой константы: int

Фактически отправленные байты данных последней передачи. Native double API устарел с 7.55.0; вариант _T использует целочисленный native счётчик.

Значение/результат: float|false.

Версии: Устарело с libcurl 7.55.0. Native API: libcurl 7.4.1.

PHP: CURLINFO_SIZE_UPLOAD; libcurl: CURLINFO_SIZE_UPLOAD

CURLINFO_SIZE_UPLOAD_T
Тип самой константы: int

Фактически отправленные байты данных последней передачи. В native это curl_off_t; границы конкретного PHP/platform преобразования всё равно проверять для очень больших значений.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.50.0 Native API: libcurl 7.55.0.

PHP: CURLINFO_SIZE_UPLOAD_T; libcurl: CURLINFO_SIZE_UPLOAD_T

CURLINFO_SPEED_DOWNLOAD
Тип самой константы: int

Средняя скорость получения за весь download в байтах/секунду; не мгновенная скорость и не биты/секунду. Native double API устарел с 7.55.0; вариант _T использует целочисленный native счётчик.

Значение/результат: float|false.

Версии: Устарело с libcurl 7.55.0. Native API: libcurl 7.4.1.

PHP: CURLINFO_SPEED_DOWNLOAD; libcurl: CURLINFO_SPEED_DOWNLOAD

CURLINFO_SPEED_DOWNLOAD_T
Тип самой константы: int

Средняя скорость получения за весь download в байтах/секунду; не мгновенная скорость и не биты/секунду. В native это curl_off_t; границы конкретного PHP/platform преобразования всё равно проверять для очень больших значений.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.50.0 Native API: libcurl 7.55.0.

PHP: CURLINFO_SPEED_DOWNLOAD_T; libcurl: CURLINFO_SPEED_DOWNLOAD_T

CURLINFO_SPEED_UPLOAD
Тип самой константы: int

Средняя скорость отправки за весь upload в байтах/секунду. Native double API устарел с 7.55.0; вариант _T использует целочисленный native счётчик.

Значение/результат: float|false.

Версии: Устарело с libcurl 7.55.0. Native API: libcurl 7.4.1.

PHP: CURLINFO_SPEED_UPLOAD; libcurl: CURLINFO_SPEED_UPLOAD

CURLINFO_SPEED_UPLOAD_T
Тип самой константы: int

Средняя скорость отправки за весь upload в байтах/секунду. В native это curl_off_t; границы конкретного PHP/platform преобразования всё равно проверять для очень больших значений.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.50.0 Native API: libcurl 7.55.0.

PHP: CURLINFO_SPEED_UPLOAD_T; libcurl: CURLINFO_SPEED_UPLOAD_T

CURLINFO_SSL_ENGINES
Тип самой константы: int

Список известных OpenSSL crypto engines; отдельные динамические библиотеки ещё могут отсутствовать при реальном использовании. PHP сам преобразует/освобождает native список.

Значение/результат: array|false.

Версии: Native API: libcurl 7.12.3.

PHP: CURLINFO_SSL_ENGINES; libcurl: CURLINFO_SSL_ENGINES

CURLINFO_SSL_VERIFYRESULT
Тип самой константы: int

Результат запрошенной проверки сертификата сервера: 0 положительный, ненулевой ошибка backend. Ноль при отключённой VERIFYPEER не доказывает проверенное соединение.

Значение/результат: int|false.

Версии: Native API: libcurl 7.5.

PHP: CURLINFO_SSL_VERIFYRESULT; libcurl: CURLINFO_SSL_VERIFYRESULT

CURLINFO_STARTTRANSFER_TIME
Тип самой константы: int

От начала до первого полученного libcurl байта; включает PRETRANSFER и время подготовки ответа сервером, а не только «время сервера». Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.9.2.

PHP: CURLINFO_STARTTRANSFER_TIME; libcurl: CURLINFO_STARTTRANSFER_TIME

CURLINFO_STARTTRANSFER_TIME_T
Тип самой константы: int

От начала до первого полученного libcurl байта; включает PRETRANSFER и время подготовки ответа сервером, а не только «время сервера». Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_STARTTRANSFER_TIME_T; libcurl: CURLINFO_STARTTRANSFER_TIME_T

CURLINFO_TOTAL_TIME
Тип самой константы: int

Полное время предыдущей передачи, включая DNS, соединение и обмен. Единица — секунды с дробной частью. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: float|false.

Версии: Native API: libcurl 7.4.1.

PHP: CURLINFO_TOTAL_TIME; libcurl: CURLINFO_TOTAL_TIME

CURLINFO_TOTAL_TIME_T
Тип самой константы: int

Полное время предыдущей передачи, включая DNS, соединение и обмен. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа.

Значение/результат: int|false.

Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0.

PHP: CURLINFO_TOTAL_TIME_T; libcurl: CURLINFO_TOTAL_TIME_T

CURLINFO_USED_PROXY
Тип самой константы: int

1 если предыдущая передача использовала proxy, 0 иначе. Это проверка фактического пути, а не только наличия CURLOPT_PROXY в конфигурации.

Значение/результат: int|false.

Версии: Доступно с PHP 8.5.0 и libcurl 8.7.0. Native API: libcurl 8.7.0.

PHP: CURLINFO_USED_PROXY; libcurl: CURLINFO_USED_PROXY

Диагностика: текст, заголовки и данные

VERBOSE/DEBUGFUNCTION нужны для диагностики протокола. CURLINFO_TEXT и другие значения в debug callback — типы сообщений, а не все допустимые ключи curl_getinfo. Сам тип сообщения не делает его безопасным для логирования: используйте разрешённые метрики и исключайте секреты. Не пишите полный debug output в публичные журналы.

Безопасная диагностическая запись
  1. Приложение знает ID задания
  2. После передачи получает код ошибки, статус и время
  3. В журнал идут эти разрешённые поля
  4. Authorization, Cookie и body не копируются автоматически
КонстантаНазначение, договор и границы
CURLINFO_DATA_IN
Тип самой константы: int

Необработанные входящие данные протокола: callback не получает гарантированно распакованный или декодированный body. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные.

Значение/результат: int: тип события DEBUGFUNCTION.

Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6.

PHP: CURLINFO_DATA_IN; libcurl: CURLOPT_DEBUGFUNCTION

CURLINFO_DATA_OUT
Тип самой константы: int

Исходящие данные протокола; могут содержать отправляемый body и секреты. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные.

Значение/результат: int: тип события DEBUGFUNCTION.

Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6.

PHP: CURLINFO_DATA_OUT; libcurl: CURLOPT_DEBUGFUNCTION

CURLINFO_HEADER_IN
Тип самой константы: int

Входящие заголовки или данные, похожие на заголовки выбранного протокола. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные.

Значение/результат: int: тип события DEBUGFUNCTION.

Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6.

PHP: CURLINFO_HEADER_IN; libcurl: CURLOPT_DEBUGFUNCTION

CURLINFO_HEADER_OUT
Тип самой константы: int

В DEBUGFUNCTION это тип исходящих заголовков. В PHP также специальный ключ curl_setopt($handle, CURLINFO_HEADER_OUT, true) включает их сбор, а curl_getinfo($handle, CURLINFO_HEADER_OUT) получает сохранённую строку, либо false при отсутствии. Сбор включить до запроса. Этот механизм использует внутренний debug handler/verbose; не совмещать без проверки с собственным DEBUGFUNCTION. Заголовки могут содержать Authorization и cookies. Две официальные строки каталога сведены здесь без потери обеих ролей.

Значение/результат: две роли: int типа debug; bool настройки; string|false результата.

PHP: CURLINFO_HEADER_OUT; libcurl: CURLOPT_DEBUGFUNCTION; PHP: роль в debug callback

CURLINFO_SSL_DATA_IN
Тип самой константы: int

Входящие бинарные TLS-данные, а не готовая PHP-строка текста ответа. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные.

Значение/результат: int: тип события DEBUGFUNCTION.

Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6.

PHP: CURLINFO_SSL_DATA_IN; libcurl: CURLOPT_DEBUGFUNCTION

CURLINFO_SSL_DATA_OUT
Тип самой константы: int

Исходящие бинарные TLS-данные. Не использовать как текстовый журнал прикладного запроса. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные.

Значение/результат: int: тип события DEBUGFUNCTION.

Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6.

PHP: CURLINFO_SSL_DATA_OUT; libcurl: CURLOPT_DEBUGFUNCTION

CURLINFO_TEXT
Тип самой константы: int

Информационный текст диагностики. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные.

Значение/результат: int: тип события DEBUGFUNCTION.

Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6.

PHP: CURLINFO_TEXT; libcurl: CURLOPT_DEBUGFUNCTION

CURLOPT_DEBUGFUNCTION
Тип самой константы: int

При VERBOSE=true получать сообщения семи CURLINFO_* debug типов: TEXT, HEADER_IN/OUT, DATA_IN/OUT, SSL_DATA_IN/OUT. Данные могут быть бинарными/сжатыми; тип TEXT тоже может содержать секрет. PHP callback не обязан возвращать native код 0: его договор void. CURLINFO_HEADER_OUT также имеет отдельную PHP роль опции/ключа getinfo, которую нельзя путать с типом сообщения. PHP 8.4/libcurl 7.9.6+.

Значение/результат: callable(CurlHandle, int, string): void.

По умолчанию: стандартный диагностический обработчик.

Версии: Доступно с PHP 8.4.0. Native API: libcurl 7.9.6.

PHP: CURLOPT_DEBUGFUNCTION; libcurl: CURLOPT_DEBUGFUNCTION

CURLOPT_STDERR
Тип самой константы: int

Куда libcurl пишет диагностический текст, прежде всего при VERBOSE. PHP ожидает пригодный stream resource и преобразует его для native API; это не путь-строка. Поток должен оставаться открытым во время передачи. Журнал может содержать Authorization, Cookie и персональные данные; не выводите его посетителю.

Значение/результат: resource: открытый поток для записи.

По умолчанию: stderr.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_STDERR; libcurl: CURLOPT_STDERR

CURLOPT_VERBOSE
Тип самой константы: int

Расширенная диагностика передачи в STDERR либо DEBUGFUNCTION. Может раскрывать заголовки, token, cookie и данные; даже тип CURLINFO_TEXT не гарантирует отсутствие секретов. Включать на ограниченное время в контролируемом окружении и не показывать журнал посетителю. Это не формат надёжного бизнес-лога.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1.

PHP: CURLOPT_VERBOSE; libcurl: CURLOPT_VERBOSE

CURLE и CURLPX: смысл отказа

CURLE_* — транспорт/протокол/локальный callback. HTTP 404/500 — другой уровень. CURLPX_* уточняют отказ proxy, который читают через CURLINFO_PROXY_ERROR. Один код не говорит, безопасен ли повтор: отправленный POST мог уже выполнить действие, даже если ответ потерян. Для идемпотентности нужен прикладной договор.

Разобрать отказ передачи
  1. curl_exec вернул false
  2. curl_errno определяет класс CURLE ошибки
  3. Для proxy дополнительно CURLINFO_PROXY_ERROR
  4. Собственная причина callback объясняет локальную остановку
  5. Повтор разрешается только политикой конкретной операции
КонстантаНазначение, договор и границы
CURLE_ABORTED_BY_CALLBACK
Тип самой константы: int

Callback сам потребовал остановку передачи. Различать сознательную политику отмены, лимит данных и ошибку обработчика.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_ABORTED_BY_CALLBACK; libcurl: libcurl-errors

CURLE_BAD_CALLING_ORDER
Тип самой константы: int

Сохранённое историческое имя: старый «неправильный порядок вызовов». Сейчас alias CURLE_OBSOLETE44; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_BAD_CALLING_ORDER; libcurl: libcurl-errors

CURLE_BAD_CONTENT_ENCODING
Тип самой константы: int

Получено неизвестное или непригодное для декодирования content/transfer encoding. Проверять заголовки ответа и поддержку декодера.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_BAD_CONTENT_ENCODING; libcurl: libcurl-errors

CURLE_BAD_DOWNLOAD_RESUME
Тип самой константы: int

Невозможно продолжить скачивание с заданного смещения: оно выходит за границы файла.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_BAD_DOWNLOAD_RESUME; libcurl: libcurl-errors

CURLE_BAD_FUNCTION_ARGUMENT
Тип самой константы: int

Неподходящее значение аргумента native-функции. PHP может раньше выбросить TypeError/ValueError; не ожидать этот код для любой ошибки PHP-вызова.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_BAD_FUNCTION_ARGUMENT; libcurl: libcurl-errors

CURLE_BAD_PASSWORD_ENTERED
Тип самой константы: int

Сохранённое историческое имя: старый «неправильный пароль». Сейчас alias CURLE_OBSOLETE46; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_BAD_PASSWORD_ENTERED; libcurl: libcurl-errors

CURLE_COULDNT_CONNECT
Тип самой константы: int

Не удалось установить соединение с конечным узлом или proxy. Это ещё не HTTP-ответ сервера.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_COULDNT_CONNECT; libcurl: libcurl-errors

CURLE_COULDNT_RESOLVE_HOST
Тип самой константы: int

DNS не смог разрешить имя целевого узла. Опечатка имени и недоступность DNS — разные возможные причины.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_COULDNT_RESOLVE_HOST; libcurl: libcurl-errors

CURLE_COULDNT_RESOLVE_PROXY
Тип самой константы: int

Не удалось разрешить имя proxy; это не обязательно проблема DNS самого целевого сайта.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_COULDNT_RESOLVE_PROXY; libcurl: libcurl-errors

CURLE_FAILED_INIT
Тип самой константы: int

Сбой начальной инициализации: внутренняя ошибка либо невозможность выделить базовые ресурсы.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FAILED_INIT; libcurl: libcurl-errors

CURLE_FILESIZE_EXCEEDED
Тип самой константы: int

Превышен установленный предел размера файла/передачи. Проверять собственную политику MAXFILESIZE, а не автоматически повышать её.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FILESIZE_EXCEEDED; libcurl: libcurl-errors

CURLE_FILE_COULDNT_READ_FILE
Тип самой константы: int

Для file:// не удалось открыть локальный файл: например, путь неверен или недостаточны права. Это локальная файловая ошибка, не HTTP 404.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FILE_COULDNT_READ_FILE; libcurl: libcurl-errors

CURLE_FTP_ACCESS_DENIED
Тип самой константы: int

Исторический alias CURLE_REMOTE_ACCESS_DENIED в актуальном заголовке libcurl. Удалённый ресурс недоступен; для FTP это, например, запрет смены каталога. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_ACCESS_DENIED; libcurl: libcurl-errors

CURLE_FTP_BAD_DOWNLOAD_RESUME
Тип самой константы: int

Исторический alias CURLE_BAD_DOWNLOAD_RESUME в актуальном заголовке libcurl. Некорректное смещение возобновления. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_BAD_DOWNLOAD_RESUME; libcurl: libcurl-errors

CURLE_FTP_CANT_GET_HOST
Тип самой константы: int

Внутренний сбой определения узла для нового FTP-соединения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_CANT_GET_HOST; libcurl: libcurl-errors

CURLE_FTP_CANT_RECONNECT
Тип самой константы: int

Опасное историческое имя: его числовой слот переиспользован; актуальный заголовок через OBSOLETE alias приводит к CURLE_HTTP2. Сегодня это ошибка HTTP/2 framing, а не буквальный смысл старого имени. При диагностике использовать curl_error/curl_strerror и версию libcurl.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_CANT_RECONNECT; libcurl: libcurl-errors

CURLE_FTP_COULDNT_GET_SIZE
Тип самой константы: int

Сохранённое историческое имя: старый отказ FTP SIZE. Сейчас alias CURLE_OBSOLETE32; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_COULDNT_GET_SIZE; libcurl: libcurl-errors

CURLE_FTP_COULDNT_RETR_FILE
Тип самой константы: int

FTP RETR получил неожиданный ответ либо завершился нулевой передачей в ситуации, которую libcurl признал ошибочной.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_COULDNT_RETR_FILE; libcurl: libcurl-errors

CURLE_FTP_COULDNT_SET_ASCII
Тип самой константы: int

Сохранённое историческое имя: старый отказ ASCII-режима. Сейчас alias CURLE_OBSOLETE29; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_COULDNT_SET_ASCII; libcurl: libcurl-errors

CURLE_FTP_COULDNT_SET_BINARY
Тип самой константы: int

Исторический alias CURLE_FTP_COULDNT_SET_TYPE в актуальном заголовке libcurl. Не удалось выбрать FTP-режим передачи binary или ASCII. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_COULDNT_SET_BINARY; libcurl: libcurl-errors

CURLE_FTP_COULDNT_STOR_FILE
Тип самой константы: int

Исторический alias CURLE_UPLOAD_FAILED в актуальном заголовке libcurl. Не началась загрузка; FTP-сервер мог отклонить STOR. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_COULDNT_STOR_FILE; libcurl: libcurl-errors

CURLE_FTP_COULDNT_USE_REST
Тип самой константы: int

FTP-сервер отклонил REST — команду возобновления с заданного смещения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_COULDNT_USE_REST; libcurl: libcurl-errors

CURLE_FTP_PARTIAL_FILE
Тип самой константы: int

Исторический alias CURLE_PARTIAL_FILE в актуальном заголовке libcurl. Фактический размер не совпал с ожидаемым. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_PARTIAL_FILE; libcurl: libcurl-errors

CURLE_FTP_PORT_FAILED
Тип самой константы: int

FTP PORT не принят; часто требуется корректный адрес активного соединения в FTPPORT и разрешённый сетевой маршрут.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_PORT_FAILED; libcurl: libcurl-errors

CURLE_FTP_QUOTE_ERROR
Тип самой константы: int

Исторический alias CURLE_QUOTE_ERROR в актуальном заголовке libcurl. Одна из дополнительных команд QUOTE не выполнена; для FTP ответ >=400. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_QUOTE_ERROR; libcurl: libcurl-errors

CURLE_FTP_SSL_FAILED
Тип самой константы: int

Исторический alias CURLE_USE_SSL_FAILED в актуальном заголовке libcurl. Не удалось обеспечить запрошенный уровень защищённого FTP. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_SSL_FAILED; libcurl: libcurl-errors

CURLE_FTP_USER_PASSWORD_INCORRECT
Тип самой константы: int

Опасное историческое имя: его числовой слот переиспользован; актуальный заголовок через OBSOLETE alias приводит к CURLE_FTP_ACCEPT_FAILED. Сегодня это ошибка ожидания обратного соединения active FTP, а не буквальный смысл старого имени. При диагностике использовать curl_error/curl_strerror и версию libcurl.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_USER_PASSWORD_INCORRECT; libcurl: libcurl-errors

CURLE_FTP_WEIRD_227_FORMAT
Тип самой константы: int

Не удалось разобрать строку FTP-ответа 227 на PASV.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_WEIRD_227_FORMAT; libcurl: libcurl-errors

CURLE_FTP_WEIRD_PASS_REPLY
Тип самой константы: int

После передачи FTP-пароля сервер прислал неожиданный код ответа. Не выводить сам пароль при диагностике.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_WEIRD_PASS_REPLY; libcurl: libcurl-errors

CURLE_FTP_WEIRD_PASV_REPLY
Тип самой константы: int

Ответ на FTP PASV/EPSV не удалось использовать для пассивного соединения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_WEIRD_PASV_REPLY; libcurl: libcurl-errors

CURLE_FTP_WEIRD_SERVER_REPLY
Тип самой константы: int

Исторический alias CURLE_WEIRD_SERVER_REPLY в актуальном заголовке libcurl. Не разбирается ответ сервера; новое общее имя действует с 7.51.0. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_WEIRD_SERVER_REPLY; libcurl: libcurl-errors

CURLE_FTP_WEIRD_USER_REPLY
Тип самой константы: int

Опасное историческое имя: его числовой слот переиспользован; актуальный заголовок через OBSOLETE alias приводит к CURLE_FTP_ACCEPT_TIMEOUT. Сегодня это таймаут ожидания соединения active FTP, а не буквальный смысл старого имени. При диагностике использовать curl_error/curl_strerror и версию libcurl.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_WEIRD_USER_REPLY; libcurl: libcurl-errors

CURLE_FTP_WRITE_ERROR
Тип самой константы: int

Сохранённое историческое имя: старый FTP write error. Сейчас alias CURLE_OBSOLETE20; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FTP_WRITE_ERROR; libcurl: libcurl-errors

CURLE_FUNCTION_NOT_FOUND
Тип самой константы: int

Сохранённое историческое имя: исторически отсутствовала функция zlib; код не используется с 7.53.0. Сейчас alias CURLE_OBSOLETE41; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_FUNCTION_NOT_FOUND; libcurl: libcurl-errors

CURLE_GOT_NOTHING
Тип самой константы: int

Сервер ничего не вернул в ситуации, когда протокол требовал ответ. Это не синоним корректного пустого HTTP body.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_GOT_NOTHING; libcurl: libcurl-errors

CURLE_HTTP_NOT_FOUND
Тип самой константы: int

Исторический alias CURLE_HTTP_RETURNED_ERROR в актуальном заголовке libcurl. Это не только HTTP 404: с FAILONERROR учитываются HTTP-ошибки >=400. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_HTTP_NOT_FOUND; libcurl: libcurl-errors

CURLE_HTTP_PORT_FAILED
Тип самой константы: int

Исторический alias CURLE_INTERFACE_FAILED в актуальном заголовке libcurl. Не удалось использовать выбранный исходящий сетевой интерфейс; название не описывает современный смысл. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_HTTP_PORT_FAILED; libcurl: libcurl-errors

CURLE_HTTP_POST_ERROR
Тип самой константы: int

Сохранённое историческое имя: историческая внутренняя ошибка POST; код не используется с 7.56.0. Сейчас alias CURLE_OBSOLETE34; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_HTTP_POST_ERROR; libcurl: libcurl-errors

CURLE_HTTP_RANGE_ERROR
Тип самой константы: int

Исторический alias CURLE_RANGE_ERROR в актуальном заголовке libcurl. Сервер не поддерживает или не принимает запрос диапазона. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_HTTP_RANGE_ERROR; libcurl: libcurl-errors

CURLE_HTTP_RETURNED_ERROR
Тип самой константы: int

При FAILONERROR=true HTTP-статус >=400 преобразован в ошибку libcurl. У опции есть протокольные исключения вокруг аутентификации; проверять HTTP-код отдельно.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_HTTP_RETURNED_ERROR; libcurl: libcurl-errors

CURLE_LDAP_CANNOT_BIND
Тип самой константы: int

Не выполнен LDAP bind, то есть этап связывания/аутентификации LDAP-сессии.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_LDAP_CANNOT_BIND; libcurl: libcurl-errors

CURLE_LDAP_INVALID_URL
Тип самой константы: int

Сохранённое историческое имя: старый некорректный LDAP URL. Сейчас alias CURLE_OBSOLETE62; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_LDAP_INVALID_URL; libcurl: libcurl-errors

CURLE_LDAP_SEARCH_FAILED
Тип самой константы: int

LDAP-сервер не выполнил поиск по запросу.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_LDAP_SEARCH_FAILED; libcurl: libcurl-errors

CURLE_LIBRARY_NOT_FOUND
Тип самой константы: int

Сохранённое историческое имя: старое отсутствие библиотеки. Сейчас alias CURLE_OBSOLETE40; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_LIBRARY_NOT_FOUND; libcurl: libcurl-errors

CURLE_MALFORMAT_USER
Тип самой константы: int

Сохранённое историческое имя: старый неверный формат пользователя. Сейчас alias CURLE_OBSOLETE24; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_MALFORMAT_USER; libcurl: libcurl-errors

CURLE_OBSOLETE
Тип самой константы: int

Сохранённое историческое имя: служебное устаревшее значение. Сейчас alias CURLE_OBSOLETE50; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_OBSOLETE; libcurl: libcurl-errors

CURLE_OK
Тип самой константы: int

0: libcurl не сообщил транспортной ошибки. HTTP 404/500 без FAILONERROR всё ещё могут дать CURLE_OK; статус и прикладное тело проверяются отдельно.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_OK; libcurl: libcurl-errors

CURLE_OPERATION_TIMEDOUT
Тип самой константы: int

Истёк один из применимых лимитов времени. По одному коду нельзя решить, был ли это DNS, соединение, медленный поток или общий TIMEOUT.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_OPERATION_TIMEDOUT; libcurl: libcurl-errors

CURLE_OPERATION_TIMEOUTED
Тип самой константы: int

Исторический alias CURLE_OPERATION_TIMEDOUT в актуальном заголовке libcurl. Истёк лимит времени; старое имя содержит историческое написание. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_OPERATION_TIMEOUTED; libcurl: libcurl-errors

CURLE_OUT_OF_MEMORY
Тип самой константы: int

Не выделена необходимая память. Слепое повторение той же нагрузки может усугубить ситуацию.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_OUT_OF_MEMORY; libcurl: libcurl-errors

CURLE_PARTIAL_FILE
Тип самой константы: int

Сервер сообщил ожидаемый размер, а фактически переданное количество оказалось другим — меньше или больше.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_PARTIAL_FILE; libcurl: libcurl-errors

CURLE_PROXY
Тип самой константы: int

Ошибка proxy handshake. Дополнительный CURLINFO_PROXY_ERROR уточняет SOCKS-стадию через CURLPX_*.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLE_PROXY; libcurl: libcurl-errors

CURLE_READ_ERROR
Тип самой константы: int

Не удалось читать локальный источник либо read callback сообщил ошибку. Это направление загрузки данных на сервер.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_READ_ERROR; libcurl: libcurl-errors

CURLE_RECV_ERROR
Тип самой константы: int

Ошибка получения сетевых данных.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_RECV_ERROR; libcurl: libcurl-errors

CURLE_SEND_ERROR
Тип самой константы: int

Ошибка отправки сетевых данных.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SEND_ERROR; libcurl: libcurl-errors

CURLE_SHARE_IN_USE
Тип самой константы: int

Сохранённое историческое имя: старое «share используется». Сейчас alias CURLE_OBSOLETE57; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SHARE_IN_USE; libcurl: libcurl-errors

CURLE_SSH
Тип самой константы: int

Неуточнённая ошибка SSH-сессии. Дополнительный curl_error помогает отличить проблемы ключей, входа и протокола.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с libcurl 7.16.1.

PHP: CURLE_SSH; libcurl: libcurl-errors

CURLE_SSL_CACERT
Тип самой константы: int

Исторический alias CURLE_PEER_FAILED_VERIFICATION в актуальном заголовке libcurl. Не прошла проверка сертификата/SSH fingerprint. Коды унифицированы с libcurl 7.62.0; до унификации peer verification имел другой номер. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_CACERT; libcurl: libcurl-errors

CURLE_SSL_CACERT_BADFILE
Тип самой константы: int

Не удалось прочитать файл доверенных CA: проверить путь, права, формат и CAINFO/CAPATH. Не лечить отключением проверки сертификатов.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_CACERT_BADFILE; libcurl: libcurl-errors

CURLE_SSL_CERTPROBLEM
Тип самой константы: int

Проблема локального клиентского сертификата; не смешивать с проверкой сертификата удалённого сервера.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_CERTPROBLEM; libcurl: libcurl-errors

CURLE_SSL_CIPHER
Тип самой константы: int

Не удалось использовать заданный набор шифров TLS.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_CIPHER; libcurl: libcurl-errors

CURLE_SSL_CONNECT_ERROR
Тип самой константы: int

Сбой TLS handshake. Причины включают формат/права файлов, пароли, протокол и сертификаты; нужна безопасно очищенная подробность curl_error.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_CONNECT_ERROR; libcurl: libcurl-errors

CURLE_SSL_ENGINE_NOTFOUND
Тип самой константы: int

Запрошенный криптографический engine не найден в используемом TLS backend.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_ENGINE_NOTFOUND; libcurl: libcurl-errors

CURLE_SSL_ENGINE_SETFAILED
Тип самой константы: int

Не удалось назначить выбранный SSL crypto engine по умолчанию.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_ENGINE_SETFAILED; libcurl: libcurl-errors

CURLE_SSL_PEER_CERTIFICATE
Тип самой константы: int

Исторический alias CURLE_PEER_FAILED_VERIFICATION в актуальном заголовке libcurl. Не прошла проверка удалённой стороны; это не проблема локального клиентского сертификата. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_PEER_CERTIFICATE; libcurl: libcurl-errors

CURLE_SSL_PINNEDPUBKEYNOTMATCH
Тип самой константы: int

Ключ сервера не совпал с PINNEDPUBLICKEY. Автоматически принимать новый ключ при этом нельзя.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_SSL_PINNEDPUBKEYNOTMATCH; libcurl: libcurl-errors

CURLE_TELNET_OPTION_SYNTAX
Тип самой константы: int

Исторический alias CURLE_SETOPT_OPTION_SYNTAX в актуальном заголовке libcurl. Неправильный формат значения настройки; современный код не ограничен Telnet. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_TELNET_OPTION_SYNTAX; libcurl: libcurl-errors

CURLE_TOO_MANY_REDIRECTS
Тип самой константы: int

Цепочка переходов превысила MAXREDIRS. Проверять циклы и адрес назначения; бесконечное разрешение переходов не исправляет первопричину.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_TOO_MANY_REDIRECTS; libcurl: libcurl-errors

CURLE_UNKNOWN_TELNET_OPTION
Тип самой константы: int

Исторический alias CURLE_UNKNOWN_OPTION в актуальном заголовке libcurl. Неизвестная native-настройка; PHP дополнительно проверяет допустимость ключей. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_UNKNOWN_TELNET_OPTION; libcurl: libcurl-errors

CURLE_UNSUPPORTED_PROTOCOL
Тип самой константы: int

Протокол URL неизвестен или отсутствует в сборке. Проверить схему URL и curl_version()["protocols"].

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_UNSUPPORTED_PROTOCOL; libcurl: libcurl-errors

CURLE_URL_MALFORMAT
Тип самой константы: int

URL имеет неприемлемый формат. Наличие корректного формата не является разрешением обращаться к адресу.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_URL_MALFORMAT; libcurl: libcurl-errors

CURLE_URL_MALFORMAT_USER
Тип самой константы: int

Исторический alias CURLE_NOT_BUILT_IN в актуальном заголовке libcurl. Функция/протокол/опция не включены при сборке libcurl; старое имя вводит в заблуждение. Совпадение чисел не делает старое имя точным диагнозом.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_URL_MALFORMAT_USER; libcurl: libcurl-errors

CURLE_WEIRD_SERVER_REPLY
Тип самой константы: int

Ответ удалённого сервера нельзя разобрать по ожидаемому протоколу. С libcurl 7.51.0 это имя заменило FTP_WEIRD_SERVER_REPLY.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.51.0

PHP: CURLE_WEIRD_SERVER_REPLY; libcurl: libcurl-errors

CURLE_WRITE_ERROR
Тип самой константы: int

Не удалось сохранить полученные данные или write callback вернул неверное число принятых байтов/ошибку. Это направление ответа, а не отправки файла.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

PHP: CURLE_WRITE_ERROR; libcurl: libcurl-errors

CURLPX_BAD_ADDRESS_TYPE
Тип самой константы: int

Proxy указал или запрос потребовал неподдерживаемый тип адреса SOCKS.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_BAD_ADDRESS_TYPE; libcurl: CURLINFO_PROXY_ERROR

CURLPX_BAD_VERSION
Тип самой константы: int

В SOCKS-ответе оказалась неожиданная версия протокола.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_BAD_VERSION; libcurl: CURLINFO_PROXY_ERROR

CURLPX_CLOSED
Тип самой константы: int

Proxy-соединение закрыто во время согласования. Конкретная стадия может уточняться текстом ошибки.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_CLOSED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_GSSAPI
Тип самой константы: int

Не удалось выполнить GSS-API согласование SOCKS.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_GSSAPI; libcurl: CURLINFO_PROXY_ERROR

CURLPX_GSSAPI_PERMSG
Тип самой константы: int

Ошибка GSS-API защиты/разбора отдельного сообщения согласования SOCKS.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_GSSAPI_PERMSG; libcurl: CURLINFO_PROXY_ERROR

CURLPX_GSSAPI_PROTECTION
Тип самой константы: int

Не удалось согласовать требуемый уровень GSS-API защиты SOCKS.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_GSSAPI_PROTECTION; libcurl: CURLINFO_PROXY_ERROR

CURLPX_IDENTD
Тип самой константы: int

SOCKS4-сервер сообщил, что не может соединиться с identd клиента (ответ 92).

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_IDENTD; libcurl: CURLINFO_PROXY_ERROR

CURLPX_IDENTD_DIFFER
Тип самой константы: int

SOCKS4-сервер сообщил несовпадение user ID с identd (ответ 93).

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_IDENTD_DIFFER; libcurl: CURLINFO_PROXY_ERROR

CURLPX_LONG_HOSTNAME
Тип самой константы: int

Имя целевого узла слишком длинное для соответствующего поля SOCKS; длина поля считается в байтах.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_LONG_HOSTNAME; libcurl: CURLINFO_PROXY_ERROR

CURLPX_LONG_PASSWD
Тип самой константы: int

Пароль не помещается в поле SOCKS5 user/password; предел протокола — 255 байтов, а не символов Unicode.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_LONG_PASSWD; libcurl: CURLINFO_PROXY_ERROR

CURLPX_LONG_USER
Тип самой константы: int

Имя пользователя слишком длинное для доступного поля/буфера SOCKS; у SOCKS5 user/password предел поля — 255 байтов.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_LONG_USER; libcurl: CURLINFO_PROXY_ERROR

CURLPX_NO_AUTH
Тип самой константы: int

Не найден разрешённый и поддерживаемый способ SOCKS-аутентификации; сервер может вернуть «нет приемлемого метода».

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_NO_AUTH; libcurl: CURLINFO_PROXY_ERROR

CURLPX_OK
Тип самой константы: int

0: подробный proxy-код отсутствует или равен успеху. В частности, если ответа proxy нет, значение тоже 0; это не отдельное доказательство успешного соединения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_OK; libcurl: CURLINFO_PROXY_ERROR

CURLPX_RECV_ADDRESS
Тип самой константы: int

Не удалось получить адресную часть proxy-ответа.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_RECV_ADDRESS; libcurl: CURLINFO_PROXY_ERROR

CURLPX_RECV_AUTH
Тип самой константы: int

Ошибка чтения ответа proxy-аутентификации.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_RECV_AUTH; libcurl: CURLINFO_PROXY_ERROR

CURLPX_RECV_CONNECT
Тип самой константы: int

Не удалось получить ожидаемый ответ при установлении SOCKS-соединения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_RECV_CONNECT; libcurl: CURLINFO_PROXY_ERROR

CURLPX_RECV_REQACK
Тип самой константы: int

Не удалось получить подтверждение запроса SOCKS.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_RECV_REQACK; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED
Тип самой константы: int

SOCKS5 reply 8: сервер не поддерживает тип адреса.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_COMMAND_NOT_SUPPORTED
Тип самой константы: int

SOCKS5 reply 7: запрошенная команда не поддерживается.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_COMMAND_NOT_SUPPORTED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_CONNECTION_REFUSED
Тип самой константы: int

SOCKS5 reply 5: конечный узел отказал в соединении.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_CONNECTION_REFUSED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_GENERAL_SERVER_FAILURE
Тип самой константы: int

SOCKS5 reply 1: общая ошибка сервера proxy.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_GENERAL_SERVER_FAILURE; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_HOST_UNREACHABLE
Тип самой константы: int

SOCKS5 reply 4: конечный host недоступен.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_HOST_UNREACHABLE; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_NETWORK_UNREACHABLE
Тип самой константы: int

SOCKS5 reply 3: целевая сеть недоступна.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_NETWORK_UNREACHABLE; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_NOT_ALLOWED
Тип самой константы: int

SOCKS5 reply 2: правила proxy запрещают соединение.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_NOT_ALLOWED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_TTL_EXPIRED
Тип самой константы: int

SOCKS5 reply 6: истёк TTL при обработке соединения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_TTL_EXPIRED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REPLY_UNASSIGNED
Тип самой константы: int

SOCKS5 вернул незарезервированный/неизвестный код ответа.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REPLY_UNASSIGNED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_REQUEST_FAILED
Тип самой константы: int

Proxy отказал в запросе; для SOCKS4 это ответ 91.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_REQUEST_FAILED; libcurl: CURLINFO_PROXY_ERROR

CURLPX_RESOLVE_HOST
Тип самой константы: int

Не разрешено имя целевого узла на стадии подготовки SOCKS; место DNS зависит от типа SOCKS proxy.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_RESOLVE_HOST; libcurl: CURLINFO_PROXY_ERROR

CURLPX_SEND_AUTH
Тип самой константы: int

Не удалось отправить данные proxy-аутентификации.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_SEND_AUTH; libcurl: CURLINFO_PROXY_ERROR

CURLPX_SEND_CONNECT
Тип самой константы: int

Не удалось отправить данные согласования proxy-соединения.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_SEND_CONNECT; libcurl: CURLINFO_PROXY_ERROR

CURLPX_SEND_REQUEST
Тип самой константы: int

Не удалось отправить SOCKS-запрос.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_SEND_REQUEST; libcurl: CURLINFO_PROXY_ERROR

CURLPX_UNKNOWN_FAIL
Тип самой константы: int

Неизвестный отказ proxy, не сопоставленный более точному виду.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_UNKNOWN_FAIL; libcurl: CURLINFO_PROXY_ERROR

CURLPX_UNKNOWN_MODE
Тип самой константы: int

Proxy выбрал неизвестный или не поддерживаемый приложением способ аутентификации.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_UNKNOWN_MODE; libcurl: CURLINFO_PROXY_ERROR

CURLPX_USER_REJECTED
Тип самой константы: int

SOCKS5 user/password-аутентификация отвергнута сервером.

Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0

PHP: CURLPX_USER_REJECTED; libcurl: CURLINFO_PROXY_ERROR

Возможности установленной libcurl

CURL_VERSION_* — биты возможностей в curl_version()[features], а не номера версии PHP. Некоторые исторические биты сохранены для совместимости и больше ничего не включают. CURLVERSION_NOW — отдельное понятие версии структуры native API. Нужные библиотеки/протоколы могут отсутствовать даже в новой libcurl.

Наличие константы и поддержка функции в установленной библиотеке — разные проверки. curl_version сообщает сборку: версия, список протоколов, битовая маска features, TLS backend. Эти значения меняются между компьютерами; следующий пример выводит проверяемую структуру, не выдумывает одинаковую строку версии для всех.

Паспорт установленной библиотеки
  1. curl_version → массив
  2. version → строка версии
  3. protocols → список схем
  4. features & бит → доступна ли возможность

Этот вариант. HTTP/2 может быть доступен или отсутствовать: обе сборки сохраняют смысл примера. Чтобы увидеть своё значение, отдельно выведите var_export($hasHttp2, true). Даже feature=true не означает, что конкретный сервер согласует этот протокол. Для WebSocket проверяйте также список protocols.

Получить паспорт сборки без сетевого запросаСамостоятельный пример
<?php
declare(strict_types=1);

$version = curl_version();
echo is_string($version['version']) ? "Версия — строка\n" : "Ошибка структуры\n";
echo is_array($version['protocols']) ? "Протоколы — список\n" : "Ошибка структуры\n";
$hasHttp2 = ($version['features'] & CURL_VERSION_HTTP2) !== 0;
echo is_bool($hasHttp2) ? "Наличие HTTP/2 проверено как bool\n" : "Ошибка типа\n";
Ожидаемый результат
Версия — строка
Протоколы — список
Наличие HTTP/2 проверено как bool
КонстантаНазначение, договор и границы
CURLVERSION_NOW
Тип самой константы: int

Версия структуры native curl_version_info, для которой собран заголовок. В PHP аргумент curl_version устарел с 8.4 и фактически игнорируется: вызывайте curl_version() без аргумента. Это не строка установленной версии libcurl.

Значение/результат: int: версия структуры native version-info, не бит features.

PHP: CURLVERSION_NOW; libcurl: curl_version_info

CURL_VERSION_ALTSVC
Тип самой константы: int

Бит поддержки разбора HTTP Alt-Svc и связанных настроек альтернативных сервисов. Сам по себе не включает хранение/использование Alt-Svc в handle.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.6 и libcurl 7.64.1

PHP: CURL_VERSION_ALTSVC; libcurl: curl_version_info

CURL_VERSION_ASYNCHDNS
Тип самой константы: int

Бит асинхронного DNS resolver: уменьшает блокировки multi и позволяет более точно соблюдать таймауты, в том числе Windows. Не означает, что любой PHP-код стал асинхронным.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.10.7

PHP: CURL_VERSION_ASYNCHDNS; libcurl: curl_version_info

CURL_VERSION_BROTLI
Тип самой константы: int

Сборка умеет распаковывать HTTP Content-Encoding br через Brotli; запрос/декодирование включают отдельно через ACCEPT_ENCODING.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.57.0

PHP: CURL_VERSION_BROTLI; libcurl: curl_version_info

CURL_VERSION_CONV
Тип самой константы: int

Историческая поддержка перекодирования через callbacks. С libcurl 7.82.0 бит всегда 0, механизм устарел. Это не способ проверить поддержку UTF-8 в приложении.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.15.4

PHP: CURL_VERSION_CONV; libcurl: curl_version_info

CURL_VERSION_CURLDEBUG
Тип самой константы: int

Исторический бит отладки памяти libcurl; с 8.19.0 совпадает с DEBUG и устарел. Не является включённым CURLOPT_VERBOSE.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.6 и libcurl 7.19.6

PHP: CURL_VERSION_CURLDEBUG; libcurl: curl_version_info

CURL_VERSION_DEBUG
Тип самой константы: int

libcurl собран с возможностями отладки; это свойство сборки, а не включение вывода сетевых секретов.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.10.6

PHP: CURL_VERSION_DEBUG; libcurl: curl_version_info

CURL_VERSION_GSASL
Тип самой константы: int

Сборка использует GNU SASL и поддерживает дополнительные SCRAM-SHA способы аутентификации.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0

PHP: CURL_VERSION_GSASL; libcurl: curl_version_info

CURL_VERSION_GSSAPI
Тип самой константы: int

libcurl связан с GSS-API для Kerberos/SPNEGO; в соответствующем окружении возможны credentials текущего пользователя.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.38.0

PHP: CURL_VERSION_GSSAPI; libcurl: curl_version_info

CURL_VERSION_GSSNEGOTIATE
Тип самой константы: int

Устаревший бит HTTP GSS-Negotiate; с libcurl 7.38.0 вместо него ориентируются на GSSAPI/SPNEGO и реальные методы сборки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.10.6 (deprecated as of libcurl 7.38.0)

PHP: CURL_VERSION_GSSNEGOTIATE; libcurl: curl_version_info

CURL_VERSION_HSTS
Тип самой константы: int

Сборка поддерживает HSTS. Проверка бита не включает HSTS cache; HSTS_CTRL/HSTS настраиваются отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0

PHP: CURL_VERSION_HSTS; libcurl: curl_version_info

CURL_VERSION_HTTP2
Тип самой константы: int

В сборке есть HTTP/2. Сервер, TLS/ALPN и политика handle ещё должны позволить фактический HTTP/2.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.33.0

PHP: CURL_VERSION_HTTP2; libcurl: curl_version_info

CURL_VERSION_HTTP3
Тип самой константы: int

В сборке есть HTTP/3 и QUIC. Присутствие самой PHP-константы не означает установленного бита; учебная Windows-сборка может иметь константу без HTTP/3.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.66.0

PHP: CURL_VERSION_HTTP3; libcurl: curl_version_info

CURL_VERSION_HTTPS_PROXY
Тип самой константы: int

Есть поддержка TLS-соединения к HTTPS proxy. Это отдельный TLS-слой от HTTPS конечного сервера.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0

PHP: CURL_VERSION_HTTPS_PROXY; libcurl: curl_version_info

CURL_VERSION_IDN
Тип самой константы: int

Есть поддержка интернационализированных доменов IDNA. Это не Unicode-нормализация произвольных частей URL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.12.0

PHP: CURL_VERSION_IDN; libcurl: curl_version_info

CURL_VERSION_IPV6
Тип самой константы: int

Сборка умеет IPv6; доступность маршрута и AAAA у конкретного узла проверяются отдельно.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_VERSION_IPV6; libcurl: curl_version_info

CURL_VERSION_KERBEROS4
Тип самой константы: int

Исторический Kerberos V4 для FTP; legacy-бит устарел с libcurl 7.33.0. Не выбирать его для современной настройки входа.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_VERSION_KERBEROS4; libcurl: curl_version_info

CURL_VERSION_KERBEROS5
Тип самой константы: int

Поддерживается Kerberos V5 для соответствующих протоколов/аутентификации, например FTP, IMAP, LDAP, POP3, SMTP и SOCKS5.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0

PHP: CURL_VERSION_KERBEROS5; libcurl: curl_version_info

CURL_VERSION_LARGEFILE
Тип самой константы: int

Сборка поддерживает большие файлы, включая размеры >2 GiB. Точность PHP int/float и возможности файловой системы остаются отдельными ограничениями.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с libcurl 7.33.0

PHP: CURL_VERSION_LARGEFILE; libcurl: curl_version_info

CURL_VERSION_LIBZ
Тип самой константы: int

Есть zlib для HTTP deflate/gzip возможностей. Наличие библиотеки не включает автоматическую распаковку без соответствующей настройки.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_VERSION_LIBZ; libcurl: curl_version_info

CURL_VERSION_MULTI_SSL
Тип самой константы: int

Сборка включает несколько TLS backends. Это не означает одновременную проверку соединения всеми backend; curl_version сообщает активный и доступные.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.56.0

PHP: CURL_VERSION_MULTI_SSL; libcurl: curl_version_info

CURL_VERSION_NTLM
Тип самой константы: int

Есть поддержка HTTP NTLM; фактическая аутентификация зависит от разрешённых HTTPAUTH/PROXYAUTH и сервера.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.10.6

PHP: CURL_VERSION_NTLM; libcurl: curl_version_info

CURL_VERSION_NTLM_WB
Тип самой константы: int

Историческое делегирование NTLM winbind helper; функция удалена из libcurl 8.8.0. Наличие константы не восстанавливает удалённый механизм.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.22.0

PHP: CURL_VERSION_NTLM_WB; libcurl: curl_version_info

CURL_VERSION_PSL
Тип самой константы: int

Есть Public Suffix List для отказа от cookies на публичный суффикс. Это часть cookie domain policy, не общий фильтр URL.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.6 и libcurl 7.47.0

PHP: CURL_VERSION_PSL; libcurl: curl_version_info

CURL_VERSION_SPNEGO
Тип самой константы: int

Есть механизм SPNEGO для согласования аутентификации.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.10.8

PHP: CURL_VERSION_SPNEGO; libcurl: curl_version_info

CURL_VERSION_SSL
Тип самой константы: int

Есть TLS/SSL возможности, например HTTPS/FTPS. Конкретные версии протокола и шифры определяет TLS backend.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

PHP: CURL_VERSION_SSL; libcurl: curl_version_info

CURL_VERSION_SSPI
Тип самой константы: int

Windows-сборка использует SSPI для поддерживаемых Kerberos/NTLM/SPNEGO/Digest механизмов и, при настройке, credentials текущего пользователя.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.13.2

PHP: CURL_VERSION_SSPI; libcurl: curl_version_info

CURL_VERSION_TLSAUTH_SRP
Тип самой константы: int

TLS backend поддерживает SRP-аутентификацию. Эта специализированная возможность не равна обычной проверке X.509 сертификата.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.3.0 и libcurl 7.21.4

PHP: CURL_VERSION_TLSAUTH_SRP; libcurl: curl_version_info

CURL_VERSION_UNICODE
Тип самой константы: int

Поддержка Windows Unicode в именах файлов и передаваемых native-опциях. HTTP body остаётся байтами и автоматически в UTF-8 не преобразуется.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.72.0

PHP: CURL_VERSION_UNICODE; libcurl: curl_version_info

CURL_VERSION_UNIX_SOCKETS
Тип самой константы: int

Поддерживаются Unix domain sockets. Это локальный транспорт до сервиса; формат HTTP поверх него остаётся отдельным протоколом.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0

PHP: CURL_VERSION_UNIX_SOCKETS; libcurl: curl_version_info

CURL_VERSION_ZSTD
Тип самой константы: int

Поддерживается HTTP Content-Encoding zstd через библиотеку Zstandard.

Значение/результат: int: значение или битовая маска, не CURLOPT-ключ.

Версии: Доступно с PHP 8.2.0 и libcurl 7.72.0

PHP: CURL_VERSION_ZSTD; libcurl: curl_version_info

Старые имена, неработающие и удалённые настройки

Старый код нужно уметь прочитать, поэтому устаревшие имена сохранены с точными ограничениями. Alias может работать, неработающая опция может успешно приниматься, удалённая может вообще не существовать. Проверка defined защищает только обращение к имени; она не превращает старое поведение в современное.

Прочитать старый пример
  1. Определить имя и его старое назначение
  2. Проверить alias/deprecated/removed статус
  3. Выбрать действующую замену по договору
  4. Не подавлять предупреждение вместо исправления причины
КонстантаНазначение, договор и границы
CURLOPT_BINARYTRANSFER
Тип самой константы: int

С PHP5.5 ничего не делает, с PHP8.4 константа deprecated. Двоичные строки RETURNTRANSFER сохраняет без этой опции. Для сохранения изображения не требуется «включать бинарность».

Значение/результат: исторический bool.

По умолчанию: не действует.

Версии: Не используется с PHP 5.5.0. Устарело с PHP 8.4.0.

PHP: CURLOPT_BINARYTRANSFER

CURLOPT_DNS_USE_GLOBAL_CACHE
Тип самой константы: int

Старый глобальный DNS cache был нетредобезопасен; native не использует его с7.62, PHP8.4 также явно сообщает отсутствие эффекта. Для совместного кеша использовать share с CURL_LOCK_DATA_DNS. Историческое автоматическое включение в non-threaded PHP не является современным контрактом.

Значение/результат: исторический bool.

По умолчанию: не действует в текущем PHP.

Версии: Доступно с libcurl 7.9.3 and deprecated as of libcurl 7.11.1. Native API: libcurl 7.9.3.

PHP: CURLOPT_DNS_USE_GLOBAL_CACHE; libcurl: CURLOPT_DNS_USE_GLOBAL_CACHE

CURLOPT_EGDSOCKET
Тип самой константы: int

Путь к сокету Entropy Gathering Daemon, исторически альтернативный RANDOM_FILE. Native считает опцию бесполезной и deprecated с7.84; современный TLS backend сам использует системный источник случайности.

Значение/результат: историческая string|null.

По умолчанию: не действует.

Версии: Доступно с libcurl 7.7.0 and deprecated as of libcurl 7.84.0. Native API: libcurl 7.7.

PHP: CURLOPT_EGDSOCKET; libcurl: CURLOPT_EGDSOCKET

CURLOPT_FTPASCII
Тип самой константы: int

Старый alias TRANSFERTEXT для ASCII FTP: native deprecated с7.11.1, последний старый символ7.15.5. PHP-константа удалена с7.3. Не использовать без проверки defined; новый код TRANSFERTEXT. Это не полноценная Unicode-перекодировка.

Значение/результат: исторический bool.

По умолчанию: удалена из PHP7.3.

Версии: Доступно с libcurl 7.1, deprecated as of libcurl 7.11.1 and last available in libcurl 7.15.5. Удалено с PHP 7.3.0. Native API CURLOPT_TRANSFERTEXT: libcurl 7.1.1.

PHP: CURLOPT_FTPASCII; libcurl: CURLOPT_TRANSFERTEXT

CURLOPT_KRB4LEVEL
Тип самой константы: int

Историческое имя KRBLEVEL. clear/safe/confidential/private выбирали FTP Kerberos protection, неузнанная непустая строка означала private, null выключал. Старое имя deprecated с7.17; современный KRBLEVEL тоже больше не служит цели и deprecated с8.17. Не рекомендовать Kerberos4 новым приложениям.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.3.0 and deprecated as of libcurl 7.17.0. Native API CURLOPT_KRBLEVEL: libcurl 7.16.4.

PHP: CURLOPT_KRB4LEVEL; libcurl: CURLOPT_KRBLEVEL

CURLOPT_KRBLEVEL
Тип самой константы: int

Исторический FTP Kerberos security level: clear,safe,confidential,private; неизвестное непустое значение выбирало private, null отключал. Сlibcurl8.17 deprecated, современная native-страница говорит об отсутствии назначения. Это сохранённое совместимое имя, а не современный путь настройки TLS.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.16.4 and deprecated as of libcurl 8.17.0. Native API: libcurl 7.16.4.

PHP: CURLOPT_KRBLEVEL; libcurl: CURLOPT_KRBLEVEL

CURLOPT_MUTE
Тип самой константы: int

Старое подавление вывода cURL; native deprecated7.8, последнее старое имя7.15.5. Для получения ответа строкой в PHP применяется RETURNTRANSFER; он не скрывает все ошибки и не равен глобальному отключению журналов.

Значение/результат: исторический bool.

По умолчанию: удалена из PHP7.3.

Версии: Доступно с libcurl 7.1.0, deprecated as of libcurl 7.8.0 and last available in libcurl 7.15.5. Удалено с PHP 7.3.0.

PHP: CURLOPT_MUTE

CURLOPT_PASSWDFUNCTION
Тип самой константы: int

Раньше callback(resource $handle,string $prompt,int $maxLength):string возвращал пароль по запросу. Native deprecated7.11.1, последнее старое имя7.15.5. Современный код заранее задаёт подходящие PASSWORD/KEYPASSWD из контролируемого источника, а не интерактивно спрашивает в web-request.

Значение/результат: исторический callable.

По умолчанию: удалена из PHP7.3.

Версии: Доступно с libcurl 7.4.2, deprecated as of libcurl 7.11.1 and last available in libcurl 7.15.5. Удалено с PHP 7.3.0.

PHP: CURLOPT_PASSWDFUNCTION

CURLOPT_PUT
Тип самой константы: int

Исторический HTTP PUT upload; native deprecated с 7.12.1, используйте UPLOAD с readable stream и ожидаемым INFILESIZE(_LARGE). CUSTOMREQUEST="PUT" меняет лишь имя метода и сам не подключает поток данных.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.12.1. Native API CURLOPT_UPLOAD: libcurl 7.1.

PHP: CURLOPT_PUT; libcurl: CURLOPT_UPLOAD

CURLOPT_RANDOM_FILE
Тип самой константы: int

Старый файл seed для SSL RNG. С libcurl7.84 deprecated и не служит цели; современный TLS backend использует свои безопасные источники. Не пытаться улучшить криптографию случайным самодельным seed-файлом.

Значение/результат: историческая string|null.

По умолчанию: не используется.

Версии: Доступно с libcurl 7.7.0 and deprecated as of libcurl 7.84.0. Native API: libcurl 7.7.

PHP: CURLOPT_RANDOM_FILE; libcurl: CURLOPT_RANDOM_FILE

CURLOPT_SOCKS5_GSSAPI_SERVICE
Тип самой константы: int

Историческое имя сервиса SOCKS5 для GSSAPI; deprecated в native с 7.49, используйте PROXY_SERVICE_NAME. Не путать с hostname proxy.

Значение/результат: string|null.

По умолчанию: rcmd.

Версии: Доступно с libcurl 7.19.4 and deprecated as of libcurl 7.49.0. Native API: libcurl 7.19.4.

PHP: CURLOPT_SOCKS5_GSSAPI_SERVICE; libcurl: CURLOPT_SOCKS5_GSSAPI_SERVICE

CURLOPT_SSLCERTPASSWD
Тип самой константы: int

Исторический alias KEYPASSWD, deprecated имя с 7.17. Пароль нужен для приватного ключа/контейнера, а не обычного публичного PEM-сертификата. Новый код KEYPASSWD; секрет хранить вне исходников.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.1.0 and deprecated as of libcurl 7.17.0. Native API CURLOPT_KEYPASSWD: libcurl 7.17.0.

PHP: CURLOPT_SSLCERTPASSWD; libcurl: CURLOPT_KEYPASSWD

CURLOPT_SSLKEYPASSWD
Тип самой константы: int

Старое имя KEYPASSWD для пароля приватного SSL ключа, native deprecated с 7.17. Не сохранять пароль в публичном PHP файле примера или журнале; новый код KEYPASSWD.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.9.3 and deprecated as of libcurl 7.17.0. Native API CURLOPT_KEYPASSWD: libcurl 7.17.0.

PHP: CURLOPT_SSLKEYPASSWD; libcurl: CURLOPT_KEYPASSWD

CURLOPT_SSL_ENABLE_NPN
Тип самой константы: int

Старое согласование прикладного протокола NPN. С libcurl 7.86 опция deprecated и не действует; современный путь — ALPN. true не включает отсутствующую поддержку HTTP/2.

Значение/результат: bool.

По умолчанию: исторически true.

Версии: Доступно с PHP 7.0.7 и libcurl 7.36.0, and deprecated as of libcurl 7.86.0. Native API: libcurl 7.36.0.

PHP: CURLOPT_SSL_ENABLE_NPN; libcurl: CURLOPT_SSL_ENABLE_NPN

CURLOPT_SSL_FALSESTART
Тип самой константы: int

Историческое сокращение TLS handshake: отправить данные до получения Finished от другой стороны. Зависит от TLS backend; deprecated с libcurl 8.15. Не универсальное ускорение и не основание ослаблять проверки сертификата.

Значение/результат: bool.

По умолчанию: false.

Версии: Доступно с PHP 7.0.7 и libcurl 7.42.0. Устарело с libcurl 8.15.0. Native API: libcurl 7.42.0.

PHP: CURLOPT_SSL_FALSESTART; libcurl: CURLOPT_SSL_FALSESTART

CURLOPT_TLSAUTH_PASSWORD
Тип самой константы: int

Секрет TLS-SRP вместе с TLSAUTH_USERNAME и TYPE=SRP. Это аутентификация внутри TLS, не пароль HTTP Basic. Native deprecated с 8.22, TLS 1.3 SRP не поддерживает. Не включать в новый общий рецепт HTTPS и не выводить в журнал.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.21.4. Native API: libcurl 7.21.4.

PHP: CURLOPT_TLSAUTH_PASSWORD; libcurl: CURLOPT_TLSAUTH_PASSWORD

CURLOPT_TLSAUTH_TYPE
Тип самой константы: int

Исторически поддерживаемый тип — SRP, требующий общего секрета/имени и соответствующей сборки TLS. Deprecated с libcurl 8.22. Если нужен HTTP Bearer или Basic, выбирать HTTPAUTH, а не эту настройку.

Значение/результат: string|null.

По умолчанию: не задан.

Версии: Доступно с libcurl 7.21.4. Native API: libcurl 7.21.4.

PHP: CURLOPT_TLSAUTH_TYPE; libcurl: CURLOPT_TLSAUTH_TYPE

CURLOPT_TLSAUTH_USERNAME
Тип самой константы: int

Имя пользователя TLS-SRP; вместе с TLSAUTH_PASSWORD может активировать SRP согласно native договору. Не имя из обычной HTTP-аутентификации. Семейство deprecated с 8.22; не совместимо с TLS 1.3.

Значение/результат: string|null.

По умолчанию: null.

Версии: Доступно с libcurl 7.21.4. Native API: libcurl 7.21.4.

PHP: CURLOPT_TLSAUTH_USERNAME; libcurl: CURLOPT_TLSAUTH_USERNAME

Native имена, упомянутые в PHP-документации

В официальном тексте встречаются также native имена, которые не являются PHP-константами этой версии расширения. Они сохранены здесь, чтобы читатель не потерял смысл описания и не скопировал необъявленный идентификатор. Это отдельный слой, не дополнительные экспортированные значения.

Упомянутое native имяЧто использовать/понимать в PHP
CURLE_USE_SSL_FAILED

Native имя ошибки обязательного TLS. PHP экспортирует историческое CURLE_FTP_SSL_FAILED; имя из native текста не следует вызывать как необъявленную PHP-константу.

CURLE_FTP_SSL_FAILED

CURLE_RTSP_SESSION_ERROR

Native имя несоответствия RTSP Session ID. Native код 86 может прийти числом в curl_errno, хотя PHP не экспортирует имя. Для сообщения используйте curl_strerror/curl_error и сохраняйте контекст RTSP; не подменяйте код другой похожей ошибкой.

CURLOPT_RTSP_SESSION_ID

CURLGSSAPI_DELEGATION_NONE

Native нулевое значение: не делегировать GSSAPI credentials. Для PHP-опции GSSAPI_DELEGATION это 0; отдельное имя PHP не экспортирует.

CURLOPT_GSSAPI_DELEGATION

CURLOPT_MAIL_RCPT_ALLOWFAILS

Современное правильное native написание. PHP сохраняет историческое MAIL_RCPT_ALLLOWFAILS с тремя L; не исправляйте его на отсутствующий PHP-идентификатор.

CURLOPT_MAIL_RCPT_ALLLOWFAILS

CURL_HET_DEFAULT

Native рекомендуемая задержка Happy Eyeballs; для описанного текущего договора 200 ms. В PHP задайте число/собственную политику через HAPPY_EYEBALLS_TIMEOUT_MS, а не необъявленное имя.

CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS

CURL_MAX_WRITE_SIZE

Native предел типичной порции данных write callback (обычно 16 KiB), не гарантированный размер каждого chunk и не лимит всего ответа. PHP не экспортирует это имя; callback принимает фактическую длину строки.

CURLOPT_WRITEFUNCTION

CURL_UPKEEP_INTERVAL_DEFAULT

Native default интервала upkeep 60000 ms. PHP не экспортирует имя; обслуживание всё равно требует явного curl_upkeep.

CURLOPT_UPKEEP_INTERVAL_MS

Практика после справочника: выберите три настройки своего клиента и запишите для каждой тип, единицы/default, ожидаемый эффект и границу проверки. Затем добавьте обработку отказа конфигурации до curl_exec. Не переносите в приложение все найденные флаги: каждый должен отвечать конкретному требованию.

Полный указатель cURL по действиям

Все функции и методы этой категории связаны с подробными карточками. Настройки и константы расположены выше по семействам; старые методы и изменения версий помечены в соответствующих местах.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

curl_closeПрочитать старый код освобождения cURL: в PHP8 функция ничего не закрывает и с8.5 устарела.

PHP4.0.2+; NOP8.0; deprecated8.5 · curl

curl_close(CurlHandle $handle): void

Завершить работу с клиентом после получения нужного текста. В PHP8 CurlHandle — объект; curl_close больше не освобождает его ресурсы, а с 8.5 устарел. Современный код прекращает хранить ненужные ссылки. Текст ответа остаётся обычной строкой.

unset($client)
  1. Выполнить GET и проверить 200
  2. Сохранить тело в $body
  3. unset удаляет эту ссылку на CurlHandle
  4. echo читает уже полученный текст

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Завершить работу с клиентом после получения нужного текстаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
unset($client);
echo $body;
Ожидаемый результат
Молоток — 8 шт.

Вывод после unset показывает, что срок жизни клиента и полученной строки различается. Если ещё есть ссылки на тот же объект, одной unset недостаточно для его уничтожения.

Ошибки и следующий шаг. Не путайте освобождение PHP-объекта с удалением active easy handle из multi. Исторический контракт curl_close сохранён ниже с опытом deprecated; новый код не подавляет его ради привычного вызова.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Прочитать старый код освобождения cURL: в PHP8 функция ничего не закрывает и с8.5 устарела.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleCurlHandle с PHP8; прежде resource.
ВерсииДо PHP8 закрывала ресурс; с8.0 NOP, с8.5 deprecated. Старый пример PHP.net про удаление handle относится к прошлому поведению.
ВозвратНет возвращаемого результата. В современном PHP жизнью объекта управляют ссылки; unset удаляет конкретную ссылку, не все ссылки во всём приложении.
Убрать ссылку не равно закрыть все чужие ссылки
  1. $first держит CurlHandle
  2. $second = $first — тот же объект
  3. unset($first) удаляет первую ссылку
  4. $second всё ещё держит объект

Этот вариант. Оставленная ссылка из callback или multi handle может продлить жизнь объекта. Не рассчитывайте, что один unset остановит любую активную передачу.

Понять обычное время жизни объектаСамостоятельный пример
<?php
declare(strict_types=1);

$first = curl_init();
if ($first === false) { throw new RuntimeException('cURL unavailable'); }
$second = $first;
unset($first);
var_dump($second instanceof CurlHandle);
unset($second);
echo "references released\n";
Ожидаемый результат
bool(true)
references released

Этот вариант. Обработчик нужен исключительно для воспроизводимого исторического опыта. Рабочий новый код не подавляет deprecated, а убирает бесполезный вызов. Для активной multi-передачи используйте соответствующее удаление handle.

Увидеть deprecated и отсутствие эффекта в PHP8.5Самостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$deprecated = 0;
set_error_handler(function (int $level) use (&$deprecated): bool {
    if ($level !== E_DEPRECATED) { return false; }
    $deprecated++; return true;
});
try { curl_close($handle); }
finally { restore_error_handler(); }
var_dump($deprecated, curl_setopt($handle, CURLOPT_URL, 'https://example.invalid/'));
Ожидаемый результат
int(1)
bool(true)

Связанные операции: curl_init; curl_multi_remove_handle.

curl_copy_handleСделать отдельный клиент с теми же настройками, затем изменить только адрес или другие различия.

PHP5+ · curl

curl_copy_handle(CurlHandle $handle): CurlHandle|false

Настроить два похожих запроса к разным товарам. Копируется конфигурация в самостоятельный CurlHandle. Обычное $second=$first оставило бы два имени одного объекта и изменило первый URL при настройке второго.

curl_copy_handle($first)
  1. Первый клиент: id1 и таймауты
  2. Копия: те же опции, затем URL id2
  3. Два последовательных запроса
  4. Молоток 8, затем Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Настроить два похожих запроса к разным товарамПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$first = curl_init($base . '/product?id=1');
if ($first === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($first, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$second = curl_copy_handle($first);
if ($second === false) { throw new RuntimeException('Клиент не скопирован'); }
curl_setopt($second, CURLOPT_URL, $base . '/product?id=2');
foreach ([$first, $second] as $client) {
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
}
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Изменился адрес только копии. foreach здесь запускает запросы по очереди; копирование само по себе не даёт параллельности.

Ошибки и следующий шаг. Копия конфигурации не является независимой копией файлов, объектов callback и истории передачи. Для одновременно выполняемых запросов нужен multi, а для разделения пользовательских сессий — явная политика состояния.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Сделать отдельный клиент с теми же настройками, затем изменить только адрес или другие различия.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleИсходный CurlHandle, настройки которого копируются.
Возврат / ошибкиНовый CurlHandle либо false; PHP8.5.11 при неудачном клонировании выдаёт E_WARNING и false.
Граница копииЭто копия конфигурации, не снимок уже идущей передачи. Соединения, TLS-сессии и текущие cookies не обещаются как скопированное состояние. Ресурсы/объекты callback могут оставаться общими ссылками.
Альтернативы$other=$handle сохраняет ссылку на тот же объект. clone CurlHandle в PHP8.5.11 использует тот же handler, но при неудаче бросает исключение вместо false.
Общий шаблон и независимый адрес
  1. Настроить первый handle
  2. curl_copy_handle → новый объект
  3. Изменить URL второго
  4. Первый URL остаётся прежним

Этот вариант. Никакие запросы не выполняются. Подготовка двух конфигураций ещё не означает параллельное выполнение: для него нужен multi-цикл.

Менять копию, сохраняя исходную настройкуСамостоятельный пример
<?php
declare(strict_types=1);

$first = curl_init('https://example.invalid/catalog');
if ($first === false) { throw new RuntimeException('cURL unavailable'); }
$second = curl_copy_handle($first);
if ($second === false) { throw new RuntimeException('Copy failed'); }
curl_setopt($second, CURLOPT_URL, 'https://example.invalid/orders');
echo curl_getinfo($first, CURLINFO_EFFECTIVE_URL), "\n";
echo curl_getinfo($second, CURLINFO_EFFECTIVE_URL), "\n";
var_dump($first === $second);
Ожидаемый результат
https://example.invalid/catalog
https://example.invalid/orders
bool(false)

Этот вариант. Объект присваивается как та же идентичность. Самостоятельная копия настроек — явное действие, которое полезно для двух похожих запросов.

Увидеть разницу обычного присваивания и копииСамостоятельный пример
<?php
declare(strict_types=1);

$first = curl_init();
if ($first === false) { throw new RuntimeException('cURL unavailable'); }
$alias = $first;
curl_setopt($alias, CURLOPT_URL, 'https://example.invalid/shared');
echo curl_getinfo($first, CURLINFO_EFFECTIVE_URL), "\n";
$copy = curl_copy_handle($first);
if ($copy === false) { throw new RuntimeException('Copy failed'); }
var_dump($alias === $first, $copy === $first);
Ожидаемый результат
https://example.invalid/shared
bool(true)
bool(false)

Если callback пишет в тот же открытый файл или использует объект со счётчиком, копирование handle не делает этот внешний объект независимым. По современному контракту libcurl share-состояние также не наследуется автоматически; задавайте требуемый обмен кэшами явно. Не копируйте handle посреди вызова callback/активной обработки.

Связанные операции: curl_init; curl_reset; curl_multi_add_handle.

curl_resetСбросить настройки клиента перед новым сценарием, помня, что кэши и cookies могут остаться.

PHP5.5+ · curl

curl_reset(CurlHandle $handle): void

Перейти от POST-расчёта к новому GET без прежних опций. Сброс возвращает опции к исходным, включая URL и RETURNTRANSFER. После него задаём полный необходимый набор заново. Кеши и cookies не обещаются очищенными.

curl_reset($client)
  1. Клиент настроен на POST
  2. reset убирает настройки, но сохраняет объект
  3. Заново URL id2, RETURNTRANSFER и лимиты
  4. GET возвращает Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перейти от POST-расчёта к новому GET без прежних опцийПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
curl_setopt($client, CURLOPT_POSTFIELDS, 'unused=1');
curl_reset($client);
curl_setopt($client, CURLOPT_URL, $base . '/product?id=2');
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
Ожидаемый результат
Перчатки — 15 шт.

В этом минимальном опыте прежний POST только настроен, но не отправлялся. После reset выполняется именно новый GET. Ни старая форма, ни её тело серверу не посланы.

Ошибки и следующий шаг. Не используйте reset как единственную изоляцию клиентов разных пользователей: cookies и кеши могут сохраняться. Полная история требует отдельного объекта/политики хранения.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Сбросить настройки клиента перед новым сценарием, помня, что кэши и cookies могут остаться.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleСуществующий CurlHandle, объект не заменяется.
Что сбрасываетсяОпции, включая URL, заданный curl_init, RETURNTRANSFER, заголовки и callbacks. После сброса заново задайте полный необходимый набор.
Что не гарантируетсяcurl_easy_reset сохраняет соединения, DNS/TLS session caches, cookies, shares и Alt-Svc cache. Это не изоляция разных пользователей.
ОшибкиВ PHP8.5.11 reset из callback того же handle бросает Error. Возвращаемого значения нет.
Сброс опций не стирает всю историю
  1. Клиент был настроен на POST
  2. curl_reset
  3. Нужно заново задать URL и получение тела
  4. Cookies/кэш требуют отдельной политики

Этот вариант. Без новой настройки адреса следующий curl_exec не знает, куда обращаться.

Увидеть сброс начального URLСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init('https://example.invalid/orders');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
echo curl_getinfo($handle, CURLINFO_EFFECTIVE_URL), "\n";
curl_reset($handle);
var_dump(curl_getinfo($handle, CURLINFO_EFFECTIVE_URL));
Ожидаемый результат
https://example.invalid/orders
string(0) ""

Этот вариант. Cookie добавлена локально, без HTTP. reset не подходит как единственная очистка перед обслуживанием другого пользователя. Безопаснее разделять соответствующие состояния по владельцам.

Показать сохранение cookie engine после resetСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
curl_setopt($handle, CURLOPT_COOKIEFILE, '');
curl_setopt($handle, CURLOPT_COOKIELIST, "example.invalid\tFALSE\t/\tFALSE\t0\tlesson\tready");
curl_reset($handle);
$cookies = curl_getinfo($handle, CURLINFO_COOKIELIST);
echo count($cookies), "\n";
var_dump(str_ends_with($cookies[0], "\tlesson\tready"));
Ожидаемый результат
1
bool(true)

Связанные операции: curl_init; curl_setopt_array; curl_copy_handle.

curl_strerrorПолучить общее описание CURLcode, когда под рукой есть число ошибки, например из multi-очереди.

PHP5.5+ · curl

curl_strerror(int $error_code): ?string

Объяснить ошибочный адрес до запроса и затем показать каталог. По известному CURLE-коду даёт текстовое пояснение независимо от конкретного handle. Не передавайте коды CURLM или CURLSH: у них другие словари.

curl_strerror($code)
  1. Порт 99999 недопустим → запрос не отправлен
  2. exec=false, errno=CURLE_URL_MALFORMAT
  3. Фактическая диагностика записана в transport-error.json
  4. Исправленный локальный URL → строка Молотка

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Объяснить ошибочный адрес до запроса и затем показать каталогПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init('http://127.0.0.1:99999/product?id=1');
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$body = curl_exec($client);
$code = curl_errno($client);
if ($body !== false || $code !== CURLE_URL_MALFORMAT) { throw new RuntimeException('Ожидался отказ формата URL'); }
$details = curl_strerror($code);
if (file_put_contents(__DIR__ . '/transport-error.json', json_encode($details, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)) === false) { throw new RuntimeException('Не удалось записать диагностику'); }
echo "Неверный адрес: запрос не отправлен\n";
curl_setopt($client, CURLOPT_URL, $base . '/product?id=1');
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
Ожидаемый результат
Неверный адрес: запрос не отправлен
Молоток — 8 шт.

Сервер не получал первый запрос: libcurl отклонила недопустимый порт. Второй запрос использует правильный собственный адрес. transport-error.json рядом с example.php содержит реальный код или текст выбранной диагностической функции.

Ошибки и следующий шаг. Считывайте ошибку сразу после отказа, до следующего exec. Повторять автоматически безопасно не любую операцию: после сетевого обрыва POST сервер мог уже выполнить действие. Не публикуйте диагностические URL с секретами.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Получить общее описание CURLcode, когда под рукой есть число ошибки, например из multi-очереди.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
error_codeКод семейства CURLE_* — результат easy-передачи. Коды CURLM_* и share имеют отдельные strerror.
ВозвратОбщее описание либо null по сигнатуре. Однако libcurl8.22.0 возвращает строку Unknown error для неизвестного числа; не используйте null как универсальную проверку допустимости кода.
Разницаcurl_error(handle) может содержать конкретный адрес/деталь операции; curl_strerror(code) описывает класс ошибки без состояния handle.
Код результата превращается в понятное пояснение
  1. message[result] содержит CURLE_*
  2. curl_strerror выбирает описание
  3. Журнал получает код и общий смысл
  4. Решение о повторе учитывает саму операцию

Этот вариант. Это текст текущего libcurl8.22.0. В приложении решение принимают по константе, а не по английской фразе.

Получить описание известного отказаСамостоятельный пример
<?php
declare(strict_types=1);

echo curl_strerror(CURLE_UNSUPPORTED_PROTOCOL), "\n";
Ожидаемый результат
Unsupported protocol

Этот вариант. Локальная проверка явно показывает расхождение с обещанием null на странице PHP.net. Диагностическая строка не является валидатором перечисления.

Не считать произвольное число валидным кодомСамостоятельный пример
<?php
declare(strict_types=1);

$message = curl_strerror(999999);
var_dump($message === null);
echo $message, "\n";
Ожидаемый результат
bool(false)
Unknown error

Связанные операции: curl_errno; curl_error; curl_multi_strerror; curl_share_strerror.

curl_escapeЗакодировать одно значение URL по RFC3986, сохранив границы параметра запроса.

PHP5.5+ · curl

curl_escape(CurlHandle $handle, string $string): string|false

Передать название с пробелом и амперсандом одним параметром. curl_escape кодирует байты одного значения URL, curl_unescape отменяет это кодирование. Амперсанд внутри имени не должен превратиться в разделитель двух параметров.

curl_escape($client, $text)
  1. Исходное имя: Молоток & Кисть
  2. escape → одна закодированная строка параметра
  3. GET /inspect?name=…
  4. $_GET[name] у сервера снова содержит всё имя

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать название с пробелом и амперсандом одним параметромПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$name = 'Молоток & Кисть';
$encoded = curl_escape($client, $name);
if ($encoded === false) { throw new RuntimeException('Не удалось кодировать значение'); }
curl_setopt($client, CURLOPT_URL, $base . '/inspect?name=' . $encoded);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Сервер получил имя: ', $received['query']['name'], "\n";
Ожидаемый результат
Сервер получил имя: Молоток & Кисть

Сервер разбирает query string и возвращает конкретное полученное поле. Вариант unescape дополнительно проверяет обратное преобразование на стороне клиента до передачи.

Ошибки и следующий шаг. Не кодируйте целиком URL вместе со схемой/слешами. Для нескольких параметров удобнее http_build_query; для HTML требуется другое экранирование. unescape не выполняет проверку допустимого пути или значения.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Закодировать одно значение URL по RFC3986, сохранив границы параметра запроса.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleCurlHandle; сетевой запрос для кодирования не выполняется.
stringБайты одного компонента, например поисковой фразы. Сначала выбирают кодировку текста.
ВозвратПроцентно закодированная строка либо false. Кодировать весь готовый URL нельзя: двоеточие и разделители тоже станут данными.
Значение не должно превращаться в новый параметр
  1. Фраза tea & cake
  2. Пробел → %20, & → %26
  3. Собрать ?q= с этим значением
  4. Сервер получает одну поисковую фразу

Этот вариант. %26 обозначает символ амперсанда внутри данных, а не начало следующего поля.

Сохранить амперсанд внутри значенияСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
echo curl_escape($handle, 'tea & cake'), "\n";
Ожидаемый результат
tea%20%26%20cake

Этот вариант. Для обычного кодирования можно использовать rawurlencode без handle; для нескольких полей удобнее http_build_query с PHP_QUERY_RFC3986. Экранирование не проверяет разрешённость адреса назначения.

Собрать URL поиска без выполнения запросаСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$value = curl_escape($handle, 'lamp/desk');
if ($value === false) { throw new RuntimeException('Encoding failed'); }
echo 'https://example.invalid/search?q=', $value, "\n";
var_dump($value === rawurlencode('lamp/desk'));
Ожидаемый результат
https://example.invalid/search?q=lamp%2Fdesk
bool(true)

Связанные операции: curl_unescape; curl_init.

curl_unescapeВернуть исходные байты процентно закодированного компонента URL.

PHP5.5+ · curl

curl_unescape(CurlHandle $handle, string $string): string|false

Передать название с пробелом и амперсандом одним параметром. curl_escape кодирует байты одного значения URL, curl_unescape отменяет это кодирование. Амперсанд внутри имени не должен превратиться в разделитель двух параметров.

curl_unescape($client, $text)
  1. Исходное имя: Молоток & Кисть
  2. escape → одна закодированная строка параметра
  3. GET /inspect?name=…
  4. $_GET[name] у сервера снова содержит всё имя

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать название с пробелом и амперсандом одним параметромПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$name = 'Молоток & Кисть';
$encoded = curl_escape($client, $name);
if ($encoded === false) { throw new RuntimeException('Не удалось кодировать значение'); }
$restored = curl_unescape($client, $encoded);
if ($restored !== $name) { throw new RuntimeException('Имя повреждено'); }
curl_setopt($client, CURLOPT_URL, $base . '/inspect?name=' . $encoded);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Сервер получил имя: ', $received['query']['name'], "\n";
Ожидаемый результат
Сервер получил имя: Молоток & Кисть

Сервер разбирает query string и возвращает конкретное полученное поле. Вариант unescape дополнительно проверяет обратное преобразование на стороне клиента до передачи.

Ошибки и следующий шаг. Не кодируйте целиком URL вместе со схемой/слешами. Для нескольких параметров удобнее http_build_query; для HTML требуется другое экранирование. unescape не выполняет проверку допустимого пути или значения.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Вернуть исходные байты процентно закодированного компонента URL.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleCurlHandle; запрос не выполняется.
stringПроцентно закодированная строка. Плюс остаётся плюсом, в отличие от urldecode.
ВозвратДекодированные байты либо false. Может содержать NUL/разделители; результат не становится проверенным URL или безопасным путём.
Вернуть данные, сохранив смысл разделителей
  1. tea%20%26%20cake
  2. Декодировать только значение
  3. Получить tea & cake
  4. Отдельно проверить допустимость данных

Этот вариант. Выбор зависит от формата: application/x-www-form-urlencoded интерпретирует плюс как пробел, произвольный URL-компонент не обязан.

Различить плюс и пробелСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
echo curl_unescape($handle, 'A+B%20C'), "\n";
echo urldecode('A+B%20C'), "\n";
Ожидаемый результат
A+B C
A B C

Этот вариант. Нулевой байт виден через bin2hex. Не декодируйте весь URL до разбора: закодированный %26/%2F может превратиться в структурный разделитель и изменить смысл.

Проверить байты вместо слепого выводаСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$value = curl_unescape($handle, 'A%00B');
if ($value === false) { throw new RuntimeException('Decoding failed'); }
echo strlen($value), "\n", bin2hex($value), "\n";
Ожидаемый результат
3
410042

Связанные операции: curl_escape; curl_getinfo.

curl_versionПроверить возможности именно установленной libcurl перед выбором протокола или новой настройки.

PHP 4.0.2+ · curl

curl_version(): array|false

Проверить поддержку протокола перед локальным чтением. Возвращается описание установленной libcurl и списка её протоколов. Наличие PHP curl и поддержка конкретного протокола — разные требования.

curl_version()
  1. Получить protocols и version установленной библиотеки
  2. Проверить HTTP до создания запроса
  3. Сохранить окружение в curl-environment.json
  4. Выполнить обычный запрос каталога

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Проверить поддержку протокола перед локальным чтениемПример для указанного окружения
<?php
declare(strict_types=1);

$version = curl_version();
if ($version === false || !in_array('http', $version['protocols'], true)) { throw new RuntimeException('Эта libcurl не поддерживает HTTP'); }
if (file_put_contents(__DIR__ . '/curl-environment.json', json_encode($version, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)) === false) { throw new RuntimeException('Не удалось записать окружение'); }
require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
Ожидаемый результат
Молоток — 8 шт.

Версия и возможности сохранены в локальный отчёт, а полезный результат показывает фактический HTTP-обмен. Диагностические числа не подменяют чтение товара.

Ошибки и следующий шаг. Поддержка HTTPS не означает правильную настройку доверенных CA. Не отключайте проверку TLS: в этом локальном уроке выбран HTTP только для 127.0.0.1. Версии PHP и libcurl проверяют отдельно.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Проверить возможности именно установленной libcurl перед выбором протокола или новой настройки.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
АргументыНет. Старый age устарел в7.4 и удалён из сигнатуры в8.0; не передавайте его в новом коде.
ВозвратАссоциативный массив сведений или false. Версия PHP и версия libcurl — разные значения.
featuresБитовая маска CURL_VERSION_*; оператор & проверяет нужный бит. feature_list с PHP8.4 даёт bool по именам. В changelog PHP.net встречается опечатка features_list; фактический ключ singular feature_list.
ГраницаПоддержка TLS/протокола в библиотеке не доказывает корректность сертификатов, доступность сети или поддержку функции сервером.
От доступной библиотеки к допустимой настройке
  1. curl_version сообщает фактическую сборку
  2. Проверяем HTTPS/HTTP2/нужные константы
  3. Подбираем возможности клиента
  4. Отдельно проверяем обмен с сервером

Этот вариант. Последнее true относится к проверенной сборке PHP8.5.11/libcurl8.22.0. Для переноса приложение должно обработать отсутствие нужного протокола.

Различить наличие расширения и сведения библиотекиСамостоятельный пример
<?php
declare(strict_types=1);

$version = curl_version();
if ($version === false) { throw new RuntimeException('Version unavailable'); }
var_dump(is_string($version['version']), is_int($version['version_number']));
var_dump(in_array('https', $version['protocols'], true));
Ожидаемый результат
bool(true)
bool(true)
bool(true)

Этот вариант. SSL в имени историческое: поле означает поддержку TLS-слоя. Не выключайте проверку сертификатов ради того, чтобы запрос перестал выдавать ошибку.

Посмотреть флаг TLS двумя способамиСамостоятельный пример
<?php
declare(strict_types=1);

$version = curl_version();
if ($version === false) { throw new RuntimeException('Version unavailable'); }
$hasTls = ($version['features'] & CURL_VERSION_SSL) !== 0;
var_dump($hasTls);
var_dump($version['feature_list']['SSL']);
Ожидаемый результат
bool(true)
bool(true)

Этот вариант. Такова тестовая сборка. Нельзя выводить поддержку HTTP3 из того, что версия libcurl новая. Возможности определяются также параметрами сборки и библиотеками.

Проверить доступность перед новой константойСамостоятельный пример
<?php
declare(strict_types=1);

$version = curl_version();
if ($version === false) { throw new RuntimeException('Version unavailable'); }
var_dump(defined('CURLOPT_PROTOCOLS_STR'));
var_dump($version['feature_list']['HTTP2'], $version['feature_list']['HTTP3']);
Ожидаемый результат
bool(true)
bool(true)
bool(false)
Поля результатаКак читать
version, version_numberСтроковая версия libcurl и24-битный номер.
ssl_version, ssl_version_numberОписание TLS backend; он не обязан быть OpenSSL. ssl_version_number — историческое поле, не надёжный способ разобрать современную версию backend.
libz_versionВерсия связанной zlib.
hostПлатформа, для которой собрана библиотека; не имя сайта посетителя.
ageВерсия структуры version_info libcurl, не возраст PHP или запроса.
features, feature_listБитовая маска и именованные возможности.
protocolsМассив доступных схем URL.
Дополнительные поляares/ares_num, libidn, iconv_ver_num, libssh_version, brotli_version/brotli_ver_num и другие зависят от PHP/libcurl/backend; не предполагайте наличие без проверки.

Публичный endpoint с полным phpinfo или конфигурацией не нужен. Сведения полезны в закрытой диагностике и отчёте воспроизводимости. В наших проверках libcurl8.22.0, OpenSSL3.5.8, zlib1.3.2; эти числа не означают, что любая более ранняя система работает одинаково.

Связанные операции: curl_init; curl_setopt.

curl_pauseПриостановить направление активной передачи, когда потребитель данных ещё не готов, затем явно продолжить.

PHP5.5+ · curl

curl_pause(CurlHandle $handle, int $flags): int

Принять отложенное тело ответа ровно один раз. Когда потребитель временно не готов, callback возвращает CURL_WRITEFUNC_PAUSE без сохранения порции. После готовности приложение явно продолжает приём; ту же порцию callback может получить повторно.

curl_pause($client, CURLPAUSE_CONT)
  1. Первая порция Молотка → PAUSE, пока ничего не записано
  2. Цикл объявляет resumed=true до CONT
  3. Возобновление может сразу снова вызвать callback
  4. Порция добавлена один раз → Молоток 8

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Новая конструкция именно здесьКак она участвует в обмене
function ($handle, string $chunk) ...Это обработчик полученного фрагмента тела. Его вызывает cURL во время передачи. $chunk содержит именно эту порцию байтов; return сообщает, сколько байтов принято, либо специальный сигнал паузы/отказа.
use (&$body, &$paused, &$resumed)Замыкание получает доступ к накопленному телу и двум флагам снаружи. & сохраняет связь с исходными переменными: callback и управляющий цикл наблюдают одно состояние.
Принять отложенное тело ответа ровно один разПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$body = '';
$paused = false;
$resumed = false;
curl_setopt($client, CURLOPT_WRITEFUNCTION, function ($handle, string $chunk) use (&$body, &$paused, &$resumed): int {
    if (!$resumed) { $paused = true; return CURL_WRITEFUNC_PAUSE; }
    if (strlen($body) + strlen($chunk) > 4096) { return 0; }
    $body .= $chunk;
    return strlen($chunk);
});
if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
try {
    $messages = finishTransfers($multi, function () use ($client, &$paused, &$resumed): void {
        if ($paused && !$resumed) {
            $resumed = true;
            if (curl_pause($client, CURLPAUSE_CONT) !== CURLE_OK) { throw new RuntimeException('Продолжение не удалось'); }
        }
    });
    foreach ($messages as $message) { if ($message['result'] !== CURLE_OK) { throw new RuntimeException('Передача не завершена'); } }
    if (!$paused || !$resumed || curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Ожидаемый обмен не завершён'); }
    echo $body;
} finally { curl_multi_remove_handle($multi, $client); }
Ожидаемый результат
Молоток — 8 шт.

Архив содержит полный цикл finishTransfers. Здесь готовность учебная и наступает сразу на следующем шаге; в сервисе её сообщает реальный потребитель ограниченного буфера. Возврат strlen($chunk) означает, что принята вся переданная порция.

Ошибки и следующий шаг. Это продвинутый пример после обычного exec и multi. Не задавайте pause новому неактивному handle в надежде отложить будущий запрос. Наш предел 4096 контролирует строку PHP, а не всю память libcurl при HTTP2/3 или распаковке; общий срок и транспортные лимиты также обязательны.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Приостановить направление активной передачи, когда потребитель данных ещё не готов, затем явно продолжить.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleHandle активной передачи. Вызов для нового неактивного handle не запускает ожидание и может вернуть ошибку.
flagsCURLPAUSE_RECV — приём, CURLPAUSE_SEND — отправка, CURLPAUSE_ALL — оба направления, CURLPAUSE_CONT — продолжить оба. Биты задают новое состояние, не добавочную команду sleep.
ВозвратКод CURLE_*; CURLE_OK=0 означает успех. Это int, не bool: if (!$code) здесь означает отсутствие ошибки.
CallbackМожно приостановить из разрешённого callback; WRITEFUNCTION также может вернуть CURL_WRITEFUNC_PAUSE. Непринятая порция будет передана снова при продолжении.
РискиВозобновление может синхронно вызвать callback до возвращения curl_pause. Пауза требует управления в event loop; не переносит задачу в фон. file:// для такой паузы не подходит.
Потребитель регулирует скорость приёма
  1. Callback получил порцию READY
  2. Пока не может принять → PAUSE без записи
  3. Потребитель готов → CONT
  4. Та же порция приходит снова и записывается один раз

Этот вариант. На PHP8.5.11/libcurl8.22 новый handle не имеет активной передачи. Это не аналог sleep и не способ запланировать будущий запрос.

Проверить код ошибки вместо ожидания волшебной паузыСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$status = curl_pause($handle, CURLPAUSE_CONT);
var_dump($status === CURLE_OK, $status === CURLE_BAD_FUNCTION_ARGUMENT);
Ожидаемый результат
bool(false)
bool(true)

Этот вариант. HTTP-контекст с собственным /ok. Callback сначала ничего не записывает и возвращает PAUSE; resumed устанавливается до CONT, потому что повторный callback возможен внутри этого вызова. В реальном сервисе готовность определяет ограниченный буфер/потребитель, а не немедленный учебный флаг. Общий deadline и CURLOPT_TIMEOUT исключают бесконечное ожидание. В архиве приложен http-fixture.py: запустите python http-fixture.py в отдельном терминале, а клиенту задайте переменную окружения PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8772 способом своей оболочки. Сервер слушает только loopback; после опыта остановите его Ctrl+C.

Принять отложенную порцию ровно один разПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if (!is_string($base) || $base === '') { throw new RuntimeException('Start the local HTTP fixture'); }
$handle = curl_init($base . '/ok');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
$multi = curl_multi_init();
$body = '';
$paused = false;
$resumed = false;
curl_setopt_array($handle, [CURLOPT_TIMEOUT => 3,
    CURLOPT_WRITEFUNCTION => function (CurlHandle $handle, string $chunk) use (&$body, &$paused, &$resumed): int {
        if (!$resumed) { $paused = true; return CURL_WRITEFUNC_PAUSE; }
        $body .= $chunk;
        return strlen($chunk);
    },
]);
if (curl_multi_add_handle($multi, $handle) !== CURLM_OK) { throw new RuntimeException('Add failed'); }
$deadline = hrtime(true) + 5_000_000_000;
$completed = false;
try {
    do {
        $status = curl_multi_exec($multi, $running);
        if ($status !== CURLM_OK) { throw new RuntimeException('Multi failed'); }
        if ($paused && !$resumed) {
            // Реальный потребитель сообщил бы здесь, что готов принять данные.
            $resumed = true;
            if (curl_pause($handle, CURLPAUSE_CONT) !== CURLE_OK) { throw new RuntimeException('Resume failed'); }
        }
        while (($message = curl_multi_info_read($multi)) !== false) {
            if ($message['result'] !== CURLE_OK) { throw new RuntimeException('Transfer failed'); }
            $completed = true;
        }
        if (hrtime(true) > $deadline) { throw new RuntimeException('Deadline'); }
        if ($running > 0) {
            $ready = curl_multi_select($multi, 0.1);
            if ($ready < 0) { throw new RuntimeException('Wait failed'); }
            if ($ready === 0) { usleep(1000); }
        }
    } while ($running > 0);
} finally { curl_multi_remove_handle($multi, $handle); }
var_dump($paused, $resumed, $completed);
echo $body;
Ожидаемый результат
bool(true)
bool(true)
bool(true)
READY

Пауза способна увеличить внутреннее буферизованное содержимое, особенно при HTTP2/3 и автоматической распаковке. Не считайте её абсолютным ограничением памяти. Low-speed правила тоже имеют особое поведение при паузе. Для простого запроса предпочтительнее обычный callback с понятным ограничением; multi-управление вводят при реальной необходимости. Пауза между отдельными запросами решает другую задачу.

Связанные операции: curl_multi_exec; curl_multi_select; curl_setopt; curl_exec.

curl_upkeepВыполнить предусмотренное протоколом обслуживание уже существующих соединений.

PHP8.2+; libcurl7.62+ · curl

curl_upkeep(CurlHandle $handle): bool

Отделить обслуживание соединения от повторного чтения товара. Функция выполняет предусмотренное протоколом обслуживание сохранённых соединений. Она не повторяет GET/POST и не даёт гарантии, что следующая операция будет успешной.

curl_upkeep($client)
  1. Первый HTTP1.1 GET → Молоток 8
  2. upkeep завершает проверку кеша соединений
  3. Второй явный GET → Перчатки 15
  4. Два разных тела появились от двух exec, не от upkeep

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Отделить обслуживание соединения от повторного чтения товараПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
curl_setopt($client, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
if (!curl_upkeep($client)) { throw new RuntimeException('Обслуживание не выполнено'); }
curl_setopt($client, CURLOPT_URL, $base . '/product?id=2');
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

В этой лаборатории используется HTTP1.1. Успешный вызов upkeep не выдаётся за наблюдение HTTP2 PING: для него нужен отдельный подходящий протокольный стенд.

Ошибки и следующий шаг. Не заменяйте upkeep проверку результата следующего запроса. Протокол, libcurl и интервальные настройки определяют, будет ли реальное служебное действие; true может означать, что делать ничего не требовалось.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Выполнить предусмотренное протоколом обслуживание уже существующих соединений.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleCurlHandle с потенциально сохранённым соединением/кэшем. Функция сама не создаёт бизнес-запрос.
ВерсияPHP8.2+, сборка libcurl7.62+. Проверяйте наличие на целевом сервере.
Возвратtrue при успешном выполнении проверки либо false при отказе. true не означает, что были отправлены байты или что соединение теперь гарантированно живо.
ПротоколPHP.net описывает HTTP2 PING; свежий libcurl также описывает MQTT upkeep при наличии такой поддержки. Интервал задаёт CURLOPT_UPKEEP_INTERVAL_MS; одного задания интервала недостаточно — функцию нужно вызывать.
КэшНачиная с libcurl8.10 обслуживание может затрагивать соединения общего connection cache, а не только использованные этим easy handle.
Обслуживание соединения отдельно от запроса
  1. Ранее открыто HTTP2-соединение
  2. Приложение выполняет другую работу
  3. После интервала вызывает upkeep
  4. Протокол может отправить PING, а не повторить заказ

Этот вариант. Ни одного подключения не было, но upkeep успешно завершил свою работу. Это не health-check API.

Успешная проверка ещё не доказывает наличие соединенияСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
var_dump(curl_upkeep($handle));
var_dump(curl_getinfo($handle, CURLINFO_RESPONSE_CODE));
Ожидаемый результат
bool(true)
int(0)

Этот вариант. Локально выполнен HTTP1.1; true проверено, отправка HTTP2 PING здесь не утверждается. Для PING нужен отдельный HTTP2-стенд и наблюдение протокола. Проверку TLS на внешнем HTTPS нельзя отключать по образцу старого демонстрационного кода. В архиве приложен http-fixture.py: запустите python http-fixture.py в отдельном терминале, а клиенту задайте переменную окружения PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8772 способом своей оболочки. Сервер слушает только loopback; после опыта остановите его Ctrl+C.

Отличить HTTP1.1-обмен от доказательства HTTP2 PINGПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if (!is_string($base) || $base === '') { throw new RuntimeException('Start the local HTTP fixture'); }
$handle = curl_init($base . '/ok');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
curl_setopt_array($handle, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_UPKEEP_INTERVAL_MS => 1000, CURLOPT_TIMEOUT => 3]);
$body = curl_exec($handle);
if ($body === false) { throw new RuntimeException('Transfer failed'); }
var_dump(curl_upkeep($handle));
echo $body;
Ожидаемый результат
bool(true)
READY

Это не TCP_KEEPALIVE и не гарантия от разрыва firewall. Следующая передача всё равно может завершиться ошибкой и требует обычной обработки. Длительные workers должны иметь понятную политику времени жизни соединений и нагрузки.

Связанные операции: curl_version; curl_getinfo; curl_share_init.

CURLFile::__constructПриложить существующий серверный файл к запросу: например, передать акт в сервис доставки.

PHP5.5+ · curl

new CURLFile(string $filename, ?string $mime_type = null, ?string $posted_filename = null); curl_file_create(...): CURLFile

Передать файл инвентаризации и прочитать подтверждённое содержимое. Указываем путь настоящего файла, заявленный MIME и имя multipart-части для сервера. Создание объекта само ничего не отправляет.

new CURLFile($path, $mime, $postname)
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', 'text/plain', 'stock.csv');
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Приложить существующий серверный файл к запросу: например, передать акт в сервис доставки.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
filenameПуть к локальному файлу; конструктор хранит его, не загружает байты и не подтверждает существование. NUL в пути вызывает ValueError.
mime_typeЗаявленный тип части multipart; null оставляет свойство mime пустым. При отправке пустое значение заменяется application/octet-stream. Тип не определяется по содержимому автоматически.
posted_filenameИмя для получателя. null оставляет postname пустым; при отправке fallback — name. Указывайте безопасное понятное имя явно, чтобы не передавать внутренний путь.
Результат / версииnew возвращает объект CURLFile; у метода-конструктора нет самостоятельного результата для прикладного кода. Класс и curl_file_create доступны с5.5; nullable параметры с8.0.
Один акт — три разных подписи
  1. На диске: storage/act-42.txt
  2. CURLFile: путь + text/plain + act.txt
  3. POSTFIELDS[document] → часть multipart
  4. Получатель: поле document, имя act.txt, байты акта

new CURLFile(...) создаёт описание отправляемого файла. -> обращается к методу конкретного объекта. Здесь файл уже находится на сервере PHP; это не выбор файла в браузере. Ключ массива POSTFIELDS — имя поля формы, а posted_filename — имя вложения для получателя. Браузерная загрузка и $_FILES.

Этот вариант. Файл здесь не создаётся и сеть не вызывается. Три строки — настройки, а не доказательство состоявшейся доставки.

Сначала только описать файлСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile('storage/act-42.txt', 'text/plain', 'act.txt');
echo $document->getFilename(), "\n";
echo $document->getMimeType(), "\n";
echo $document->getPostFilename(), "\n";
Ожидаемый результат
storage/act-42.txt
text/plain
act.txt

Этот вариант. Это полный отправитель для собственного локального стенда: переменная окружения PHP_MANUAL_HTTP_BASE содержит его адрес, /upload возвращает описание принятых частей JSON. Стенд проверяет байты и заголовки реальной multipart-передачи; lint и этот HTTP-запуск записаны раздельно. Внешний сервис имеет собственный контракт ответа, HTTPS и авторизацию. Схема ниже поясняет, какие поля получит PHP-приёмник. В архиве приложен upload-receiver.php. В отдельном терминале запустите php -S 127.0.0.1:8773 upload-receiver.php; в терминале клиента задайте PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8773 способом своей оболочки. Это локальный учебный приёмник малых файлов, без авторизации; для публичного upload endpoint нужны отдельные ограничения и проверки.

Отправить файл и обычное поле вместеПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if ($base === false || !str_starts_with($base, 'http://127.0.0.1:')) {
    throw new RuntimeException('Start the documented local upload fixture');
}
$path = __DIR__ . '/act.txt';
if (!is_file($path) || !is_readable($path)) { throw new RuntimeException('Act not readable'); }
$fields = ['order' => '42', 'document' => new CURLFile($path, 'text/plain', 'act.txt')];
$handle = curl_init($base . '/upload');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
if (!curl_setopt_array($handle, [
    CURLOPT_POSTFIELDS => $fields,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT_MS => 3000,
    CURLOPT_PROXY => '',
])) { throw new RuntimeException('Cannot configure upload'); }
$body = curl_exec($handle);
if ($body === false) { throw new RuntimeException(curl_error($handle)); }
if (curl_getinfo($handle, CURLINFO_RESPONSE_CODE) !== 200) {
    throw new RuntimeException('Receiver rejected upload');
}
$received = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
echo $received['fields']['order'], "\n";
echo $received['files']['document']['name'], "\n";
echo $received['files']['document']['type'], "\n";
echo $received['files']['document']['data'], "\n";
Ожидаемый результат
42
act.txt
text/plain
ACT-42

Не создавайте Content-Type: multipart/form-data вручную без boundary: cURL формирует разделитель и заголовок согласованно с телом. Передавайте массив, содержащий CURLFile, напрямую; json_encode объекта не отправит файл. Старый синтаксис @/path не используйте. Для нескольких файлов задавайте плоские ключи documents[0], documents[1]; PHP-приёмник соберёт массив $_FILES.

Проверка is_readable помогает дать понятную ошибку заранее, но файл может измениться после проверки. cURL может открыть поток уже при установке POSTFIELDS; до завершения запроса не удаляйте и не изменяйте файл. Для больших файлов CURLFile обычно разумнее чтения всего содержимого в строку. На стороне приёмника имя и MIME остаются недоверенными данными.

Связанные операции: curl_file_create; CURLStringFile::__construct; curl_setopt; curl_exec.

curl_file_createСоздать такое же файловое вложение обычной функцией, когда удобнее процедурная запись.

PHP5.5+ · curl

curl_file_create(string $filename, ?string $mime_type = null, ?string $posted_filename = null): CURLFile

Передать файл инвентаризации и прочитать подтверждённое содержимое. Указываем путь настоящего файла, заявленный MIME и имя multipart-части для сервера. Создание объекта само ничего не отправляет.

new CURLFile($path, $mime, $postname)
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', 'text/plain', 'stock.csv');
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Создать такое же файловое вложение обычной функцией, когда удобнее процедурная запись.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
АргументыТот же путь, необязательные MIME и имя получателя, что у CURLFile::__construct.
ВозвратОбъект CURLFile; функция не выполняет HTTP-запрос и не копирует файл. Неподходящий тип аргумента — TypeError, NUL в пути — ValueError.
Выбор стиляnew CURLFile и curl_file_create создают объект одного класса. Процедурное имя не означает другой способ передачи файла.
Две записи одной подготовки
  1. curl_file_create(path, mime, name)
  2. Возвращается CURLFile
  3. $fields[document] = объект
  4. curl_exec выполняет подготовленный запрос

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

Получить вложение из функцииСамостоятельный пример
<?php
declare(strict_types=1);

$document = curl_file_create('act.txt', 'text/plain', 'act-42.txt');
echo get_class($document), "\n";
echo $document->getPostFilename(), "\n";
Ожидаемый результат
CURLFile
act-42.txt

Этот вариант. == сравнивает свойства объектов одного класса, === проверяет ту же идентичность. Настройки равны, но это два разных экземпляра. Смена способа записи сама по себе не улучшает скорость запроса.

Проверить равенство настроек двух способов созданияСамостоятельный пример
<?php
declare(strict_types=1);

$fromFunction = curl_file_create('act.txt', 'text/plain', 'act-42.txt');
$fromClass = new CURLFile('act.txt', 'text/plain', 'act-42.txt');
var_dump($fromFunction == $fromClass, $fromFunction === $fromClass);
Ожидаемый результат
bool(true)
bool(false)

Связанные операции: CURLFile::__construct; CURLFile::setMimeType; curl_exec.

CURLFile::getFilenameУзнать исходный путь вложения перед отправкой и проверить, тот ли документ выбран.

PHP5.5+ · curl

CURLFile::getFilename(): string

Передать файл инвентаризации и прочитать подтверждённое содержимое. Это локальный путь чтения, а не имя, которое получит сервер. Проверка файла предшествует передаче.

$file->getFilename()
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', 'text/plain', 'stock.csv');
if (!is_file($file->getFilename())) { throw new RuntimeException('Файл инвентаризации отсутствует'); }
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Узнать исходный путь вложения перед отправкой и проверить, тот ли документ выбран.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
АргументыНет. Метод читает name текущего объекта.
ВозвратСохранённый путь, не содержимое файла и не имя на стороне получателя. Метод не проверяет существование и права.
Проверяем источник акта
  1. $document хранит act.txt
  2. getFilename → act.txt
  3. is_readable проверяет доступ сейчас
  4. Доставка проверяется отдельно по ответу

Этот вариант. В интерфейсе пользователю показывайте act.txt. Внутренний путь пригодится для собственной диагностики, но не должен бесконтрольно уходить в публичный ответ.

Различить путь и имя получателяСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile('private/act-42.txt', 'text/plain', 'act.txt');
echo $document->getFilename(), "\n";
echo $document->getPostFilename(), "\n";
Ожидаемый результат
private/act-42.txt
act.txt

Этот вариант. Маленький учебный файл создан стендом. Чтение здесь нужно для демонстрации; CURLFile не требует предварительно читать весь файл в память.

Проверить подготовленный источникСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile(__DIR__ . '/act.txt', 'text/plain', 'act.txt');
$path = $document->getFilename();
var_dump(is_file($path) && is_readable($path));
echo file_get_contents($path), "\n";
Ожидаемый результат
bool(true)
ACT-42

Связанные операции: CURLFile::__construct; CURLFile::getPostFilename.

CURLFile::getMimeTypeПроверить, какой тип содержимого вы сами задали для вложения.

PHP5.5+ · curl

CURLFile::getMimeType(): string

Передать файл инвентаризации и прочитать подтверждённое содержимое. Возвращает объявленный MIME, который cURL поставит у части. Это чтение настройки, не анализ фактических байтов файла.

$file->getMimeType()
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', 'text/plain', 'stock.csv');
if ($file->getMimeType() !== 'text/plain') { throw new RuntimeException('Проверьте объявленный тип'); }
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Проверить, какой тип содержимого вы сами задали для вложения.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
АргументыНет.
ВозвратЗначение mime. При создании без MIME это пустая строка, хотя при отправке используется application/octet-stream. Это не результат анализа файла.
Метаданные не проверяют содержимое
  1. Создали с text/plain
  2. getMimeType вернул text/plain
  3. Байты могли быть любого вида
  4. При необходимости отдельно определяем MIME через fileinfo

Этот вариант. Тип сообщает получателю, как интерпретировать часть запроса; он не превращает двоичные байты в текст.

Прочитать явный MIMEСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile('act.txt', 'text/plain', 'act.txt');
echo $document->getMimeType(), "\n";
Ожидаемый результат
text/plain

Этот вариант. Fallback application/octet-stream применяется при построении multipart. Сам getter не подставляет его. Определение MIME по данным.

Не спутать пустое свойство с типом отправкиСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile('act.txt');
var_dump($document->getMimeType());
$document->setMimeType('text/plain');
echo $document->getMimeType(), "\n";
Ожидаемый результат
string(0) ""
text/plain

Связанные операции: CURLFile::setMimeType; CURLFile::__construct.

CURLFile::getPostFilenameУзнать имя, с которым акт или отчёт будет представлен получателю.

PHP5.5+ · curl

CURLFile::getPostFilename(): string

Передать файл инвентаризации и прочитать подтверждённое содержимое. Возвращает предлагаемое серверу имя файла multipart. Оно может отличаться от локального inventory.txt; сервер не должен доверять этому имени как пути.

$file->getPostFilename()
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', 'text/plain', 'stock.csv');
echo 'Предлагаемое имя: ', $file->getPostFilename(), "\n";
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Предлагаемое имя: stock.csv
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Узнать имя, с которым акт или отчёт будет представлен получателю.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
АргументыНет.
ВозвратСохранённое postname. Без явной настройки пустая строка; fallback при передаче берётся из name. Переименование на диске не происходит.
Имя вложения отдельно от пути
  1. Источник private/order-42.dat
  2. postname = act.txt
  3. getPostFilename → act.txt
  4. Читатель получает понятное имя

Этот вариант. Этот вывод рассчитан на CLI. В HTML любое динамическое имя нужно экранировать htmlspecialchars; MIME и расширение имени должны соответствовать вашему договору.

Показать пользователю имя отправляемого актаСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile('private/order-42.dat', 'text/plain', 'act.txt');
echo 'Attachment: ', $document->getPostFilename(), "\n";
Ожидаемый результат
Attachment: act.txt

Этот вариант. Установка имени получателя не перемещает источник и не меняет имя поля document в POSTFIELDS.

Задать имя, если его забыли при созданииСамостоятельный пример
<?php
declare(strict_types=1);

$document = new CURLFile('private/order-42.dat');
if ($document->getPostFilename() === '') { $document->setPostFilename('act.txt'); }
echo $document->getPostFilename(), "\n";
echo $document->getFilename(), "\n";
Ожидаемый результат
act.txt
private/order-42.dat

Связанные операции: CURLFile::setPostFilename; CURLFile::getFilename.

CURLFile::setMimeTypeИзменить описание типа вложения перед сборкой запроса, например для подготовленного CSV.

PHP5.5+ · curl

CURLFile::setMimeType(string $mime_type): void

Передать файл инвентаризации и прочитать подтверждённое содержимое. Меняет настройку MIME до отправки. Не преобразует содержимое и не делает невалидный файл допустимым.

$file->setMimeType('text/plain')
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', '', 'stock.csv');
$file->setMimeType('text/plain');
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Изменить описание типа вложения перед сборкой запроса, например для подготовленного CSV.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
mime_typeСтрока MIME. Метод хранит строку, не преобразует данные и не доказывает правильность типа.
Возвратvoid: результата для присваивания нет. Проверяйте новое значение getter-методом. Неверный тип аргумента при strict_types — TypeError.
Когда менятьДо CURLOPT_POSTFIELDS. PHP строит multipart при установке опции; изменение объекта после неё не обязано обновить уже подготовленную часть. Установите POSTFIELDS заново.
Меняем метку подготовленного CSV
  1. CURLFile создан с пустым mime
  2. setMimeType(text/csv)
  3. getMimeType → text/csv
  4. Теперь передаём объект в POSTFIELDS

Этот вариант. Возвращать изменённый объект из метода не требуется: изменяется текущий экземпляр $report.

Уточнить MIME до отправкиСамостоятельный пример
<?php
declare(strict_types=1);

$report = new CURLFile('orders.csv', null, 'orders.csv');
$report->setMimeType('text/csv');
echo $report->getMimeType(), "\n";
Ожидаемый результат
text/csv

Этот вариант. clone CURLFile копирует настройки, но не делает копию файла на диске. Оба описания ссылаются на один источник. Согласуйте MIME с принимающим сервисом, а не меняйте его ради обхода проверки.

Подготовить другой вариант метаданных без изменения исходногоСамостоятельный пример
<?php
declare(strict_types=1);

$source = new CURLFile('orders.csv', 'text/plain', 'orders.csv');
$partnerCopy = clone $source;
$partnerCopy->setMimeType('text/csv');
echo $source->getMimeType(), "\n";
echo $partnerCopy->getMimeType(), "\n";
Ожидаемый результат
text/plain
text/csv

Связанные операции: CURLFile::getMimeType; CURLFile::setPostFilename; curl_setopt.

CURLFile::setPostFilenameДать получателю понятное имя документа без переименования серверного файла.

PHP5.5+ · curl

CURLFile::setPostFilename(string $posted_filename): void

Передать файл инвентаризации и прочитать подтверждённое содержимое. Меняет только предлагаемое имя multipart-части. Файл на диске не переименовывается.

$file->setPostFilename('stock.csv')
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLFile(__DIR__ . '/inventory.txt', 'text/plain');
$file->setPostFilename('stock.csv');
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Дать получателю понятное имя документа без переименования серверного файла.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
posted_filenameИмя вложения в multipart. Не путь для сохранения на стороне получателя и не имя поля формы.
Возвратvoid. Метод меняет postname текущего объекта.
ПорядокНастраивайте до передачи объекта в POSTFIELDS; после изменения уже использованного объекта пересоберите POSTFIELDS. Не обещайте получателю безопасное имя только потому, что строка прошла setter.
Переименовали вложение, не серверный источник
  1. Путь report-internal.dat
  2. setPostFilename(report.txt)
  3. POSTFIELDS[document] остаётся document
  4. Получатель видит report.txt

Этот вариант. Для исходного пути есть свойство name, но менять его во время уже настроенной передачи не следует.

Изменить только внешнее имяСамостоятельный пример
<?php
declare(strict_types=1);

$report = new CURLFile('report-internal.dat', 'text/plain');
$report->setPostFilename('report.txt');
echo $report->getPostFilename(), "\n";
echo $report->getFilename(), "\n";
Ожидаемый результат
report.txt
report-internal.dat

Этот вариант. Число взято из доверенной модели заказа. Произвольный ввод посетителя нельзя превращать в путь или заголовок без проверки; свой короткий шаблон снимает эту неоднозначность.

Построить имя из проверенного номера заказаСамостоятельный пример
<?php
declare(strict_types=1);

$orderId = 42;
if ($orderId <= 0) { throw new InvalidArgumentException('Invalid order'); }
$report = new CURLFile('act.txt', 'text/plain');
$report->setPostFilename('act-' . $orderId . '.txt');
echo $report->getPostFilename(), "\n";
Ожидаемый результат
act-42.txt

Связанные операции: CURLFile::getPostFilename; CURLFile::__construct; curl_setopt.

CURLStringFile::__constructПередать сгенерированный отчёт как файловое вложение прямо из строки, не создавая временный файл.

PHP8.1+ · curl

new CURLStringFile(string $data, string $postname, string $mime = "application/octet-stream")

Передать файл инвентаризации и прочитать подтверждённое содержимое. Содержимое берётся из строки PHP, а не с диска. Это удобно для небольшого сформированного отчёта; весь текст уже находится в памяти.

new CURLStringFile($data, $postname, $mime)
  1. inventory.txt содержит Молоток;8 и перевод строки
  2. Ключ inventory становится именем поля multipart
  3. PHP-сервер читает $_FILES[inventory] и свой временный файл
  4. Ответ содержит имя stock.csv и принятые байты

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать файл инвентаризации и прочитать подтверждённое содержимоеПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
$file = new CURLStringFile("Молоток;8\n", 'stock.csv', 'text/plain');
curl_setopt($client, CURLOPT_URL, $base . '/upload');
curl_setopt($client, CURLOPT_POSTFIELDS, ['inventory'=>$file]);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
$received = json_decode($body, true, 8, JSON_THROW_ON_ERROR);
echo 'Получен ', $received['name'], "\n", $received['data'];
Ожидаемый результат
Получен stock.csv
Молоток;8

Архив содержит inventory.txt и полный server.php. Сервер проверяет код загрузки, происхождение временного файла и учебный предел 4096 байт, затем возвращает фактический текст. Content-Type multipart с boundary создаёт cURL; вручную его не задаём.

Ошибки и следующий шаг. Полученный от клиента MIME и filename — недоверенные заявления. Этот приёмник не сохраняет файл постоянно и не публикует его. Для реального импорта добавьте проверку формата, доступ пользователя, лимиты на уровне сервера и политику безопасного хранения. CURLStringFile доступен с PHP8.1.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Передать сгенерированный отчёт как файловое вложение прямо из строки, не создавая временный файл.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
dataГотовые байты файла в PHP-строке. Это содержимое, не путь. Строка может содержать NUL.
postnameОбязательное имя вложения у получателя; ключ массива POSTFIELDS задаёт имя поля отдельно.
mimeТип части; по умолчанию application/octet-stream. Явный null недопустим в отличие от nullable аргумента CURLFile.
Версии / стоимостьPHP8.1+. Конструктор создаёт объект, не отправляет запрос. Содержимое уже находится в памяти; для больших существующих файлов используйте CURLFile либо потоковую передачу по договору API.
Отчёт из переменной до принимающей формы
  1. $csv = строки отчёта
  2. new CURLStringFile($csv, orders.csv, text/csv)
  3. POSTFIELDS[report] → multipart
  4. У PHP-приёмника $_FILES[report], не обычный $_POST[report]

Этот вариант. Свойства публичные. Для чтения используются ->data, ->postname и ->mime; getter/setter-методов CURLFile у этого класса нет.

Подготовить небольшой CSV в памятиСамостоятельный пример
<?php
declare(strict_types=1);

$csv = "id,total\n42,1500\n";
$report = new CURLStringFile($csv, 'orders.csv', 'text/csv');
echo $report->postname, "\n";
echo $report->mime, "\n";
echo $report->data;
Ожидаемый результат
orders.csv
text/csv
id,total
42,1500

Этот вариант. Это полный отправитель для собственного локального стенда: переменная окружения PHP_MANUAL_HTTP_BASE содержит его адрес, /upload возвращает описание принятых частей JSON. Стенд проверяет байты и заголовки реальной multipart-передачи; lint и этот HTTP-запуск записаны раздельно. Внешний сервис имеет собственный контракт ответа, HTTPS и авторизацию. Схема ниже поясняет, какие поля получит PHP-приёмник. NUL внутри содержимого сохранился; hex410042 представляет три байта A, ноль, B. В архиве приложен upload-receiver.php. В отдельном терминале запустите php -S 127.0.0.1:8773 upload-receiver.php; в терминале клиента задайте PHP_MANUAL_HTTP_BASE=http://127.0.0.1:8773 способом своей оболочки. Это локальный учебный приёмник малых файлов, без авторизации; для публичного upload endpoint нужны отдельные ограничения и проверки.

Передать строку именно как файлПример для указанного окружения
<?php
declare(strict_types=1);

$base = getenv('PHP_MANUAL_HTTP_BASE');
if ($base === false || !str_starts_with($base, 'http://127.0.0.1:')) {
    throw new RuntimeException('Start the documented local upload fixture');
}
$fields = ['report' => new CURLStringFile("A\0B", 'payload.bin')];
$handle = curl_init($base . '/upload');
if ($handle === false) { throw new RuntimeException('cURL unavailable'); }
if (!curl_setopt_array($handle, [
    CURLOPT_POSTFIELDS => $fields,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT_MS => 3000,
    CURLOPT_PROXY => '',
])) { throw new RuntimeException('Cannot configure upload'); }
$body = curl_exec($handle);
if ($body === false) { throw new RuntimeException(curl_error($handle)); }
if (curl_getinfo($handle, CURLINFO_RESPONSE_CODE) !== 200) {
    throw new RuntimeException('Receiver rejected upload');
}
$received = json_decode($body, true, flags: JSON_THROW_ON_ERROR);
echo $received['files']['report']['name'], "\n";
echo $received['files']['report']['type'], "\n";
echo $received['files']['report']['hex'], "\n";
Ожидаемый результат
payload.bin
application/octet-stream
410042

Если API ожидает целиком JSON или сырые байты тела, CURLStringFile не нужен: передайте подготовленную строку непосредственно как POSTFIELDS и согласованный Content-Type. Файловое multipart-вложение и JSON-поле — разные протоколы. Не кодируйте бинарное содержимое base64 без требования контракта: это увеличит размер и изменит получаемые байты.

Связанные операции: CURLFile::__construct; curl_setopt; curl_exec.

curl_multi_initПолучить диспетчер для нескольких независимых запросов: например, остатки и цены приходят от двух сервисов.

PHP 5+; объект с PHP 8.0 · curl

curl_multi_init(): CurlMultiHandle

Получить два самостоятельных ответа каталога. Создаёт диспетчер передач. Сами URL, таймауты и способы чтения по-прежнему принадлежат отдельным easy-клиентам.

curl_multi_init()
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Получить диспетчер для нескольких независимых запросов: например, остатки и цены приходят от двух сервисов.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
ПараметрыНет. Создание диспетчера ещё не добавляет запросы и не запускает сеть.
РезультатCurlMultiHandle с PHP 8.0; раньше resource. В PHP 8.5.11 невозможность внутреннего создания вызывает Error, не false.
МеханизмОдин PHP-код продвигает несколько передач через libcurl. Это не отдельный PHP-поток на каждый URL и не фоновая работа после завершения скрипта.
Сначала создаётся диспетчер
  1. curl_multi_init создаёт пустой multi
  2. curl_init создаёт отдельный easyhandle
  3. add_handle связывает easy с multi
  4. exec/select/info_read ведут работу

Этот вариант. instanceof проверяет класс объекта. false здесь означает отсутствие сообщения о завершении: запросов ещё нет.

Создать пустой диспетчерСамостоятельный пример
<?php
$multi = curl_multi_init();
var_dump($multi instanceof CurlMultiHandle);
var_dump(curl_multi_info_read($multi));
Ожидаемый результат
bool(true)
bool(false)

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

Этот вариант. Настройка RETURNTRANSFER включает накопление ответа. Пустой буфер до exec — не ответ сервиса и не подтверждение успеха.

Добавить первый источник, не выполняя егоСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
var_dump(curl_multi_add_handle($multi, $handle) === CURLM_OK);
var_dump(curl_multi_getcontent($handle));
curl_multi_remove_handle($multi, $handle);
Ожидаемый результат
bool(true)
string(0) ""

Связанные операции: curl_multi_add_handle; curl_multi_exec; curl_multi_info_read.

curl_multi_add_handleПередать настроенный запрос диспетчеру; набор адресов и политика одного запроса остаются у easyhandle.

PHP 4.0.2+ · curl

curl_multi_add_handle(CurlMultiHandle $multi_handle, CurlHandle $handle): int

Получить два самостоятельных ответа каталога. Присоединяет ранее настроенный клиент. Возвращаемый CURLM-код относится к добавлению, а не к статусу HTTP-ответа.

curl_multi_add_handle($multi, $client)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Передать настроенный запрос диспетчеру; набор адресов и политика одного запроса остаются у easyhandle.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleДиспетчер из curl_multi_init.
handleКлиент из curl_init. До добавления задают URL, таймауты, способ приёма ответа и остальные настройки.
ВозвратCURLM_OK (0) при успехе, иначе код CURLM_*. Повторно добавить тот же клиент нельзя; нельзя одновременно держать его в двух multi.
ВладениеУспешный add сохраняет ссылку на easyhandle внутри multi. unset вашей переменной сам по себе не отменяет передачу.
Один клиент нельзя добавить дважды
  1. Создан easy для one.txt
  2. Первый add → CURLM_OK
  3. Второй add того же объекта → ошибка
  4. В multi остаётся один клиент

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

Этот вариант. Возврат — код, не bool: проверка if($code) дала бы обратное понимание успеха.

Отличить добавление от повторного добавленияСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
echo curl_multi_add_handle($multi, $handle) === CURLM_OK ? "Added\n" : "Failed\n";
echo curl_multi_add_handle($multi, $handle) === CURLM_OK ? "Added\n" : "Duplicate rejected\n";
curl_multi_remove_handle($multi, $handle);
Ожидаемый результат
Added
Duplicate rejected

Этот вариант. Массив handles хранит связь с запросами для PHP 8.2+. До exec ни одна передача ещё не завершена. Количество handles и число одновременных сетевых соединений — не одно и то же.

Два самостоятельных клиента одного диспетчераСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$multi = curl_multi_init();
$handles = [];
foreach (['one.txt', 'two.txt'] as $file) {
    $handle = curl_init($base . $file);
    if ($handle === false) { throw new RuntimeException('Client unavailable'); }
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    if (curl_multi_add_handle($multi, $handle) !== CURLM_OK) { throw new RuntimeException('Add failed'); }
    $handles[] = $handle;
}
echo count($handles), "\n";
foreach ($handles as $handle) { curl_multi_remove_handle($multi, $handle); }
Ожидаемый результат
2

Связанные операции: curl_multi_remove_handle; curl_multi_exec; curl_setopt.

curl_multi_remove_handleУбрать один запрос из диспетчера, например при отмене или после обработки завершения.

PHP 4.0.2+ · curl

curl_multi_remove_handle(CurlMultiHandle $multi_handle, CurlHandle $handle): int

Получить два самостоятельных ответа каталога. Отсоединяет клиент от диспетчера, в том числе после завершения. Это не удаление полученной строки и не чтение сообщения о завершении.

curl_multi_remove_handle($multi, $client)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Убрать один запрос из диспетчера, например при отмене или после обработки завершения.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handle / handleДиспетчер и конкретный прикреплённый easyhandle.
ВозвратCURLM_OK=0 либо CURLM_* ошибка. Удаление активного клиента останавливает именно его передачу.
После удаленияEasyhandle остаётся объектом, его можно настроить и выполнить обычным curl_exec либо добавить в другой multi. Снимайте нужное сообщение/метрики до удаления; необработанные события очереди могут исчезнуть.
Отмена до первого шага
  1. Клиент добавлен в multi
  2. remove_handle убирает его
  3. exec пустого multi сообщает running=0
  4. Клиент можно использовать отдельно

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

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

Отменить ещё не запущенный запросСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
curl_multi_add_handle($multi, $handle);
var_dump(curl_multi_remove_handle($multi, $handle) === CURLM_OK);
curl_multi_exec($multi, $running);
echo $running, "\n";
Ожидаемый результат
bool(true)
0

Этот вариант. Убирается участие в диспетчере, а не конфигурация easyhandle. Здесь читается приложенный файл; реальный повтор HTTP POST может повторить бизнес-действие.

Повторно использовать клиента вне multiСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
curl_multi_add_handle($multi, $handle);
curl_multi_remove_handle($multi, $handle);
$body = curl_exec($handle);
if ($body === false) { throw new RuntimeException(curl_error($handle)); }
echo $body, "\n";
Ожидаемый результат
stock=7

Связанные операции: curl_multi_add_handle; curl_multi_info_read; curl_exec.

curl_multi_closeОчистить диспетчер от всех прикреплённых easyhandle, например в finally после отказа пакетной операции.

PHP 4.0.2+ · curl

curl_multi_close(CurlMultiHandle $multi_handle): void

Получить два самостоятельных ответа каталога. Удаляет все easy-клиенты из multi. В PHP8 возвращает управление без уничтожения объекта; срок жизни объекта определяется ссылками.

curl_multi_close($multi)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
}
curl_multi_close($multi);
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Очистить диспетчер от всех прикреплённых easyhandle, например в finally после отказа пакетной операции.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleОбъект диспетчера.
Возвратvoid: полезного результата нет. В PHP 8+ отсоединяет все easyhandle; сам объект multi остаётся пригодным. До PHP 8 закрывал resource и делал его непригодным.
ОтличиеВ отличие от curl_close и curl_share_close, этот вызов имеет полезное действие в PHP 8.5 и не является их deprecated no-op. Удаление всех передач не откатывает уже выполненные серверные изменения.
Очистка делает multi пустым
  1. Добавили one.txt
  2. curl_multi_close удаляет клиента из multi
  3. exec видит 0 незаконченных передач

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

Этот вариант. Переменная multi всё ещё содержит объект; пустое состояние здесь не означает уничтожение PHP-объекта.

Убрать все прикреплённые запросыСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
curl_multi_add_handle($multi, $handle);
curl_multi_close($multi);
curl_multi_exec($multi, $running);
echo $running, "\n";
var_dump($multi instanceof CurlMultiHandle);
Ожидаемый результат
0
bool(true)

Этот вариант. Можно очистить набор и собрать следующий. Если нужен отдельный жизненный цикл кешей/настроек, проще создать новый multi.

Использовать очищенный диспетчер повторноСамостоятельный пример
<?php
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
curl_multi_add_handle($multi, $handle);
curl_multi_close($multi);
var_dump(curl_multi_add_handle($multi, $handle) === CURLM_OK);
curl_multi_close($multi);
Ожидаемый результат
bool(true)

Связанные операции: curl_multi_remove_handle; curl_multi_init.

curl_multi_execСделать очередной шаг всех передач; получить код диспетчера и число ещё работающих запросов.

PHP 4.0.2+ · curl

curl_multi_exec(CurlMultiHandle $multi_handle, int &$still_running): int

Получить два самостоятельных ответа каталога. Делает очередной шаг всех передач и записывает число ещё активных в переменную running. Это число не равно числу успешных HTTP200.

curl_multi_exec($multi, $running)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Сделать очередной шаг всех передач; получить код диспетчера и число ещё работающих запросов.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleДиспетчер с настроенными клиентами.
still_runningВыходной параметр по ссылке: передайте переменную, которую PHP заполнит числом незавершённых передач. Не нужно писать & при вызове. Это число, а не тело ответа.
ВозвратCURLM_* код всего диспетчера. CURLM_OK не подтверждает успех каждой передачи; результаты читаются через info_read. running=0 тоже бывает при быстрых ошибках.
ВыполнениеMulti работает пошагово: exec продвигает работу, select ждёт возможность следующего шага. Сам PHP-скрипт с таким циклом всё ещё занят до конца; тяжёлый код между шагами задерживает передачи.
Две разные величины
  1. exec пустого multi
  2. Возврат CURLM_OK — диспетчер исправен
  3. Переменная running получает 0
  4. Очередь завершений пуста

Этот вариант. 99 заранее показывает, что функция перезаписывает переменную. Она не возвращает массив ответов.

Увидеть код и выходной параметр отдельноСамостоятельный пример
<?php
$multi = curl_multi_init();
$running = 99;
$status = curl_multi_exec($multi, $running);
var_dump($status === CURLM_OK);
echo $running, "\n";
Ожидаемый результат
bool(true)
0

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

В более длинном примере function driveTransfers($multi) задаёт повторяемый цикл, а вызов driveTransfers($multi) выполняет его. do ... while сначала делает шаг, затем проверяет количество незаконченных передач. curl_multi_select ожидает возможность нового шага; короткая usleep после 0 защищает от немедленного пустого повторения. Это политика данного цикла, а не обещание ускорить cURL. Циклы; Параметры функции.

Этот вариант. Оба пути локальные, один намеренно отсутствует. Порядок завершения не является договором, поэтому вывод сортируется. CURLM_OK нельзя подставлять вместо CURLE_OK при проверке отдельной передачи.

Исправный multi, но один источник недоступенСамостоятельный пример
<?php
function driveTransfers($multi) {
    do {
        $status = curl_multi_exec($multi, $running);
        if ($status !== CURLM_OK) {
            throw new RuntimeException(curl_multi_strerror($status));
        }
        if ($running > 0) {
            $ready = curl_multi_select($multi, 0.1);
            if ($ready === -1) { throw new RuntimeException('Wait failed'); }
            if ($ready === 0) { usleep(1000); }
        }
    } while ($running > 0);
}
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$multi = curl_multi_init();
foreach (['one.txt', 'missing.txt'] as $file) {
    $handle = curl_init($base . $file);
    if ($handle === false) { throw new RuntimeException('Client unavailable'); }
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multi, $handle);
}
try {
    driveTransfers($multi);
    $results = [];
    while (($info = curl_multi_info_read($multi)) !== false) {
        $results[] = $info['result'] === CURLE_OK ? 'ok' : 'failed';
    }
    sort($results);
    echo implode(',', $results), "\n";
} finally { curl_multi_close($multi); }
Ожидаемый результат
failed,ok

Связанные операции: curl_multi_select; curl_multi_info_read; curl_multi_getcontent.

curl_multi_selectПодождать, пока какая-то передача сможет продвинуться; убрать бесполезный опрос в тесном цикле.

PHP 4.0.2+ · curl

curl_multi_select(CurlMultiHandle $multi_handle, float $timeout = 1.0): int

Получить два самостоятельных ответа каталога. Ожидает возможности следующего шага до указанного числа секунд. Ноль означает отсутствие готовой активности за интервал, а не окончание всех передач.

curl_multi_select($multi, 0.1)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Подождать, пока какая-то передача сможет продвинуться; убрать бесполезный опрос в тесном цикле.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleДиспетчер. Перед первым ожиданием обычно выполняют exec, чтобы начать передачи.
timeoutМаксимум ожидания в секундах, default1.0. Это не общий таймаут запросов; он задаётся easy-настройками. Ноль — немедленный опрос.
ВозвратЧисло активных дескрипторов; 0 может быть нормальным отсутствием активности. −1 означает отказ ожидания. Ни 1, ни 0 не говорят, завершён ли HTTP-ответ: снова вызовите exec/info_read.
Версии / границаС PHP8.4 неверный timeout вызывает ValueError. Manual упоминает PHP_INT_MAX, но tagged8.5.11 реально проверяет 0…INT_MAX/1000, то есть 2147483.647 секунды на проверенной сборке; INF/NAN тоже недопустимы. В обычном цикле берут доли секунды, не этот максимум.
Пустой диспетчер без ожидания
  1. Нет прикреплённых передач
  2. select с timeout0 проверяет готовность
  3. Возвращает0; это не ошибка

Этот вариант. select может вернуться сразу, если нечего ждать. Цикл должен проверять running, а не бесконечно ждать на пустом multi.

Отличить отсутствие активности от отказаСамостоятельный пример
<?php
$multi = curl_multi_init();
var_dump(curl_multi_select($multi, 0.0));
Ожидаемый результат
int(0)

Этот вариант. Второй случай фиксирует реальную границу PHP8.5.11, которая уже, чем формулировка страницы PHP.net. Старые рецепты -1→sleep относились к другим реализациям; здесь -1 — отдельный отказ.

Проверить неправильное время ожидания на PHP 8.4+Самостоятельный пример
<?php
$multi = curl_multi_init();
foreach ([-1.0, 2147484.0] as $timeout) {
    try { curl_multi_select($multi, $timeout); }
    catch (ValueError $error) { echo "Invalid timeout\n"; }
}
Ожидаемый результат
Invalid timeout
Invalid timeout

Связанные операции: curl_multi_exec; curl_multi_errno; curl_multi_info_read.

curl_multi_getcontentПолучить накопленное тело конкретного запроса после завершения; отдельно проверить его транспортный результат.

PHP 4.0.2+ · curl

curl_multi_getcontent(CurlHandle $handle): ?string

Получить два самостоятельных ответа каталога. Читает тело конкретной easy-передачи при RETURNTRANSFER=true. Сам вызов не запускает сеть и не подтверждает транспортный успех.

curl_multi_getcontent($client)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Получить накопленное тело конкретного запроса после завершения; отдельно проверить его транспортный результат.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleИменно easyhandle, не CurlMultiHandle. Для накопления заранее установите CURLOPT_RETURNTRANSFER=true.
РезультатСтрока буфера, включая пустую, либо null, если выбран другой способ приёма тела. Частичный/пустой буфер ещё не доказывает успешное завершение.
Другой выводCURLOPT_WRITEFUNCTION переключает получение тела на callback; тогда не ждите сохранённого тела от getcontent. Большие тела лучше обрабатывать потоком и ограничивать объём.
Настройка меняет место ответа
  1. До RETURNTRANSFER буфер не выбран → null
  2. После настройки буфер есть, но пуст
  3. После завершения в нём будет тело

Этот вариант. Первый null описывает настройку, второй ответ — пока не наполненный буфер. Ни один не является HTTP-кодом ошибки.

Различить null и пустой буферСамостоятельный пример
<?php
$handle = curl_init();
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
var_dump(curl_multi_getcontent($handle));
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
var_dump(curl_multi_getcontent($handle));
Ожидаемый результат
NULL
string(0) ""

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

В более длинном примере function driveTransfers($multi) задаёт повторяемый цикл, а вызов driveTransfers($multi) выполняет его. do ... while сначала делает шаг, затем проверяет количество незаконченных передач. curl_multi_select ожидает возможность нового шага; короткая usleep после 0 защищает от немедленного пустого повторения. Это политика данного цикла, а не обещание ускорить cURL. Циклы; Параметры функции.

Этот вариант. Для HTTP после CURLE_OK дополнительно проверяют HTTP-статус и схему тела. Даже корректная HTTP404 обычно не транспортная ошибка.

Получить тело после сообщения DONEСамостоятельный пример
<?php
function driveTransfers($multi) {
    do {
        $status = curl_multi_exec($multi, $running);
        if ($status !== CURLM_OK) {
            throw new RuntimeException(curl_multi_strerror($status));
        }
        if ($running > 0) {
            $ready = curl_multi_select($multi, 0.1);
            if ($ready === -1) { throw new RuntimeException('Wait failed'); }
            if ($ready === 0) { usleep(1000); }
        }
    } while ($running > 0);
}
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$handle = curl_init($base . 'one.txt');
if ($handle === false) { throw new RuntimeException('Client unavailable'); }
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$multi = curl_multi_init();
curl_multi_add_handle($multi, $handle);
try {
    driveTransfers($multi);
    $info = curl_multi_info_read($multi);
    if ($info === false || $info['result'] !== CURLE_OK) { throw new RuntimeException('Transfer failed'); }
    echo curl_multi_getcontent($info['handle']), "\n";
} finally { curl_multi_close($multi); }
Ожидаемый результат
stock=7

Связанные операции: curl_multi_info_read; curl_setopt; curl_getinfo.

curl_multi_info_readЗабирать сообщения о завершившихся передачах по одному и узнавать их индивидуальные результаты.

PHP 4.0.2+ · curl

curl_multi_info_read(CurlMultiHandle $multi_handle, int &$queued_messages = null): array|false

Получить два самостоятельных ответа каталога. Возвращает следующее сообщение завершения, включая handle и result CURLE-код. Сообщения надо вычитать до false; они относятся к отдельным передачам.

curl_multi_info_read($multi)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Забирать сообщения о завершившихся передачах по одному и узнавать их индивидуальные результаты.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleДиспетчер; вызов не продвигает сеть вместо exec.
queued_messagesНеобязательная выходная переменная: число сообщений, оставшихся после успешного чтения. Если возвращён false, в PHP8.5.11 прежнее значение переменной не обновляется. Не используйте его вместо проверки результата.
ВозвратМассив: msg=CURLMSG_DONE, result=CURLE_* код, handle=CurlHandle. false означает, что сейчас нет сообщения. Очередь читается до false; один вызов не возвращает результаты всего набора.
ПорядокДо remove_handle сохраните код, тело и нужные метрики. Текст Manual с resource исторический: в PHP8 это объект; PHP-массив хранит свою ссылку, но необработанные библиотечные события после удаления не обещаны.
Пустая очередь — нормальное состояние
  1. Только создали multi
  2. info_read не находит сообщений
  3. false: сейчас нечего обрабатывать

Этот вариант. Значение12 сохранено намеренно. Ветку обработки выполняют только после $message !== false.

Не обращаться к handle у falseСамостоятельный пример
<?php
$multi = curl_multi_init();
$queued = 12;
$message = curl_multi_info_read($multi, $queued);
var_dump($message);
echo $queued, "\n";
Ожидаемый результат
bool(false)
12

В опытах file:/// указывает на приложенные локальные one.txt/two.txt. __DIR__ — папка скрипта; str_replace меняет разделитель Windows на /, ltrim убирает начальный разделитель для сборки URL. Это проверка cURL без внешней сети, не измерение сетевого параллелизма. Для HTTP дальше дан отдельный стенд.

В более длинном примере function driveTransfers($multi) задаёт повторяемый цикл, а вызов driveTransfers($multi) выполняет его. do ... while сначала делает шаг, затем проверяет количество незаконченных передач. curl_multi_select ожидает возможность нового шага; короткая usleep после 0 защищает от немедленного пустого повторения. Это политика данного цикла, а не обещание ускорить cURL. Циклы; Параметры функции.

Этот вариант. Очередь завершают до false, даже если running уже0. Отсутствие сообщений сейчас не означает, что ещё работающие запросы закончены.

Прочитать всю очередь завершенийСамостоятельный пример
<?php
function driveTransfers($multi) {
    do {
        $status = curl_multi_exec($multi, $running);
        if ($status !== CURLM_OK) {
            throw new RuntimeException(curl_multi_strerror($status));
        }
        if ($running > 0) {
            $ready = curl_multi_select($multi, 0.1);
            if ($ready === -1) { throw new RuntimeException('Wait failed'); }
            if ($ready === 0) { usleep(1000); }
        }
    } while ($running > 0);
}
$base = 'file:///' . ltrim(str_replace('\\', '/', __DIR__), '/') . '/';
$multi = curl_multi_init();
foreach (['one.txt', 'two.txt'] as $file) {
    $handle = curl_init($base . $file);
    if ($handle === false) { throw new RuntimeException('Client unavailable'); }
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multi, $handle);
}
$bodies = [];
try {
    driveTransfers($multi);
    while (($info = curl_multi_info_read($multi, $queued)) !== false) {
        if ($info['msg'] !== CURLMSG_DONE || $info['result'] !== CURLE_OK) { throw new RuntimeException('Transfer failed'); }
        $bodies[] = curl_multi_getcontent($info['handle']);
        curl_multi_remove_handle($multi, $info['handle']);
    }
} finally { curl_multi_close($multi); }
sort($bodies);
echo implode('|', $bodies), "\n";
Ожидаемый результат
price=450|stock=7

Связанные операции: curl_multi_exec; curl_multi_getcontent; curl_multi_remove_handle; curl_errno.

curl_multi_errnoУзнать последний код ошибки диспетчера; не спутать его с HTTP-ошибкой одного сервиса.

PHP 7.1+; объект/int с PHP8 · curl

curl_multi_errno(CurlMultiHandle $multi_handle): int

Получить два самостоятельных ответа каталога. Диагностирует ошибку диспетчера. Ошибки отдельных easy-запросов берутся из сообщений завершения, статусы HTTP — через getinfo.

curl_multi_errno($multi)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
$dispatcherCode = curl_multi_errno($multi);
if ($dispatcherCode !== CURLM_OK) { throw new RuntimeException(curl_multi_strerror($dispatcherCode)); }
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Узнать последний код ошибки диспетчера; не спутать его с HTTP-ошибкой одного сервиса.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleОбъект multi.
РезультатЦелый CURLM_* код, успех0. С PHP8 результат int, прежний false больше не часть договора. Следующие операции могут обновить код.
Отдельные передачиИх CURLE_* результат берут из info_read. Код multi=0 не отменяет DNS/TLS/timeout ошибки отдельного клиента.
Диспетчер ещё исправен
  1. Создали multi
  2. multi_errno читает последнее состояние
  3. 0 означает отсутствие ошибки диспетчера

Этот вариант. Это не тест интернет-соединения: не запускалась ни одна передача.

Прочитать начальное состояниеСамостоятельный пример
<?php
$multi = curl_multi_init();
var_dump(curl_multi_errno($multi) === CURLM_OK);
Ожидаемый результат
bool(true)

Этот вариант. Снимок получен сразу после повторного добавления. Текст ошибки можно получить через multi_strerror.

Диагностика ошибки набораСамостоятельный пример
<?php
$multi = curl_multi_init();
$handle = curl_init();
curl_multi_add_handle($multi, $handle);
$status = curl_multi_add_handle($multi, $handle);
var_dump($status !== CURLM_OK);
var_dump(curl_multi_errno($multi) === $status);
curl_multi_close($multi);
Ожидаемый результат
bool(true)
bool(true)

Связанные операции: curl_multi_strerror; curl_multi_info_read.

curl_multi_strerrorПеревести CURLM_* код диспетчера в техническую строку для журнала.

PHP5.5+ · curl

curl_multi_strerror(int $error_code): ?string

Получить два самостоятельных ответа каталога. Объясняет именно CURLM-код диспетчера. Словари CURLE, CURLM и CURLSH не взаимозаменяемы.

curl_multi_strerror($code)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Перевести CURLM_* код диспетчера в техническую строку для журнала.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
error_codeCURLM_* код, например возврат add_handle/exec или multi_errno. CURLE_* коды отдельной передачи сюда не подставляют.
ВозвратСтрока либо null по PHP-сигнатуре. В проверенной libcurl8.22 неизвестный код тоже даёт строку Unknown error, поэтому строка не подтверждает допустимость кода. Точная английская фраза не является договором бизнес-логики.
Число превращается в подпись
  1. Передаём CURLM_OK
  2. Получаем техническую строку
  3. Приложение проверяет число, не английскую фразу

Этот вариант. Сравнивается наличие описания, чтобы пример не зависел от формулировки конкретной libcurl.

Проверить доступность описанияСамостоятельный пример
<?php
$text = curl_multi_strerror(CURLM_OK);
var_dump(is_string($text) && $text !== '');
Ожидаемый результат
bool(true)

Этот вариант. Подпись пригодна для диагностики. Пользователю сервиса сообщают понятную причину на его языке, без внутреннего списка констант.

Подписать фактическую ошибкуСамостоятельный пример
<?php
$multi = curl_multi_init();
$handle = curl_init();
curl_multi_add_handle($multi, $handle);
$status = curl_multi_add_handle($multi, $handle);
$description = curl_multi_strerror($status);
var_dump($status !== CURLM_OK, is_string($description));
curl_multi_close($multi);
Ожидаемый результат
bool(true)
bool(true)

Связанные операции: curl_multi_errno; curl_strerror.

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

PHP5.5+ · curl

curl_multi_setopt(CurlMultiHandle $multi_handle, int $option, mixed $value): bool

Получить два самостоятельных ответа каталога. Задаёт лимит соединений диспетчера до выполнения. Он не равен гарантированной скорости или числу одновременно занятых серверных работников.

curl_multi_setopt($multi, CURLMOPT_MAX_TOTAL_CONNECTIONS, 2)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
if (!curl_multi_setopt($multi, CURLMOPT_MAX_TOTAL_CONNECTIONS, 2)) { throw new RuntimeException('Лимит не применён'); }
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

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

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleОбъект multi; это не easyhandle с CURLOPT_* настройками.
optionПоддерживаемая CURLMOPT_* константа. Неизвестное значение в PHP8.5.11 вызывает ValueError.
valueТип и смысл определяет option: целый лимит/битовая маска либо callable для PUSHFUNCTION. Неверный callback даёт TypeError. Возврат true/false сообщает результат настройки.
ЛимитыMAX_TOTAL_CONNECTIONS/MAX_HOST_CONNECTIONS ограничивают соединения, MAXCONNECTS — кеш соединений. Это не rate-limit «запросов в секунду». HTTP2 несколько запросов может вести одним соединением.
ВерсииPUSHFUNCTION с PHP7.1; MAX_CONCURRENT_STREAMS с PHP8.2 (libcurl7.67+). MAX_HOST/TOTAL_CONNECTIONS, MAX_PIPELINE_LENGTH, CHUNK_LENGTH/CONTENT_LENGTH_PENALTY_SIZE с PHP7.0.7. Исторический HTTP1 pipelining больше не поддерживается современной libcurl.
Не открыть сотни соединений сразу
  1. Создали multi
  2. Настроили максимум2 всего и1 на хост
  3. Будущие передачи соблюдают параметры соединений

Этот вариант. Само принятие настройки ещё не измеряет параллелизм. Большую очередь приложения всё равно нужно ограничивать по памяти и требованиям партнёра.

Задать ограничения соединенийСамостоятельный пример
<?php
$multi = curl_multi_init();
var_dump(curl_multi_setopt($multi, CURLMOPT_MAX_TOTAL_CONNECTIONS, 2));
var_dump(curl_multi_setopt($multi, CURLMOPT_MAX_HOST_CONNECTIONS, 1));
Ожидаемый результат
bool(true)
bool(true)

Этот вариант. Полный список опций: CURLMOPT_* и связанные перечисления. Пользовательские числа/имена callback нельзя без проверки превращать в конфигурацию клиента.

Отделить неизвестную настройку от falseСамостоятельный пример
<?php
$multi = curl_multi_init();
try { curl_multi_setopt($multi, 999999, 1); }
catch (ValueError $error) { echo "Unknown option\n"; }
try { curl_multi_setopt($multi, CURLMOPT_PUSHFUNCTION, 'missing_handler'); }
catch (TypeError $error) { echo "Invalid callback\n"; }
Ожидаемый результат
Unknown option
Invalid callback

Связанные операции: curl_multi_exec; curl_setopt; curl_multi_errno.

curl_multi_get_handlesПосмотреть все easyhandle, прикреплённые к multi, без собственного списка ссылок; дополнительный API PHP8.5.

PHP8.5+ · curl

curl_multi_get_handles(CurlMultiHandle $multi_handle): array

Получить два самостоятельных ответа каталога. Возвращает присоединённые easy-клиенты. Их можно сопоставить с запросами, но наличие клиента в этом массиве не означает завершённую передачу.

curl_multi_get_handles($multi)
  1. Созданы два easy-клиента: id1 и id2
  2. multi-loop.php чередует exec и ожидание, собирая сообщения
  3. Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
  4. Тела выводятся в выбранном порядке: Молоток 8, Перчатки 15

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Перед выполнением прочитайте устройство finishTransfers и полный multi-loop.php. Это наша функция ожидания и сбора завершений; её файл входит в архив.

Получить два самостоятельных ответа каталогаПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
require __DIR__ . '/multi-loop.php';
$multi = curl_multi_init();
$clients = [];
foreach ([1, 2] as $id) {
    $client = curl_init($base . '/product?id=' . $id);
    if ($client === false) { throw new RuntimeException('Клиент не создан'); }
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
    if (curl_multi_add_handle($multi, $client) !== CURLM_OK) { throw new RuntimeException('Клиент не добавлен'); }
    $clients[] = $client;
}
$clients = curl_multi_get_handles($multi);
$messages = finishTransfers($multi);
foreach ($messages as $message) {
    if ($message['result'] !== CURLE_OK) { throw new RuntimeException(curl_error($message['handle'])); }
}
foreach ($clients as $client) {
    if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
    echo curl_multi_getcontent($client);
    curl_multi_remove_handle($multi, $client);
}
unset($client, $clients, $messages, $multi);
Ожидаемый результат
Молоток — 8 шт.
Перчатки — 15 шт.

Архив содержит полный multi-loop.php. finishTransfers — наша функция, не встроенный API: она вызывает exec, читает info_read и ждёт select до завершения. Два полученных тела показывают результат каждой передачи; сервер остаётся собственным локальным PHP-процессом.

Ошибки и следующий шаг. PHP development server в этой установке может обслуживать запросы последовательно: этот опыт проверяет управление несколькими передачами, не обещает ускорения. Код CURLM_OK не означает успех всех запросов. В большом клиенте освобождение handles при исключениях оформляют try/finally, ограничивают общий размер тел и число заданий.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Посмотреть все easyhandle, прикреплённые к multi, без собственного списка ссылок; дополнительный API PHP8.5.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
multi_handleДиспетчер из curl_multi_init.
ВозвратМассив прикреплённых CurlHandle, в том числе уже завершённых, но ещё не удалённых; пустой массив у пустого multi. Это снимок списка объектов, не тела ответов и не только running-запросы.
ВладениеЭлементы являются ссылками на те же объекты, не клонами. Изменение PHP-массива не добавляет/не удаляет клиентов в multi; use add/remove. Сам массив удерживает объекты пока существует.
Версия/источникДобавлена в PHP8.5, подтверждена официальной migration85.new-functions и tagged stub/multi.c; отдельная страница функции на момент сверки возвращала404. До8.5 храните свой массив клиентов.
Список клиентов — не список ответов
  1. Пустой multi → []
  2. Добавили клиента
  3. get_handles вернул тот же объект в массиве

Этот вариант. Нужен PHP8.5+. Строгое сравнение объектов проверяет идентичность: это тот же клиент.

Получить список прикреплённых объектовСамостоятельный пример
<?php
$multi = curl_multi_init();
echo count(curl_multi_get_handles($multi)), "\n";
$handle = curl_init();
curl_multi_add_handle($multi, $handle);
$handles = curl_multi_get_handles($multi);
echo count($handles), "\n";
var_dump($handles[0] === $handle);
curl_multi_close($multi);
Ожидаемый результат
0
1
bool(true)

Этот вариант. Старый массив хранит объект, но не возвращает его в диспетчер. На отмену передачи влияет remove, а не unset элемента снимка.

Отличить снимок массива от состояния multiСамостоятельный пример
<?php
$multi = curl_multi_init();
$handle = curl_init();
curl_multi_add_handle($multi, $handle);
$snapshot = curl_multi_get_handles($multi);
curl_multi_remove_handle($multi, $handle);
echo count($snapshot), "\n";
echo count(curl_multi_get_handles($multi)), "\n";
Ожидаемый результат
1
0

Связанные операции: curl_multi_add_handle; curl_multi_remove_handle; curl_multi_info_read.

curl_share_initСоздать общий кеш для нескольких cURL-клиентов одной операции, например использовать одну cookie-сессию партнёра.

PHP5.5+; объект с PHP8 · curl

curl_share_init(): CurlShareHandle

Передать выбор темы между двумя клиентами одного пользователя. Создаёт отдельный объект общих кешей. Пока явно не выбрана категория и клиенты не присоединены, их cookies не начинают делиться автоматически.

curl_share_init()
  1. Первый клиент посылает GET без Cookie
  2. Сервер отвечает Set-Cookie: theme=blue%20sky
  3. Cookie engine сохраняет значение в общем share
  4. Второй клиент отправляет Cookie и получает тему blue sky

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать выбор темы между двумя клиентами одного пользователяПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) { throw new RuntimeException(curl_share_strerror(curl_share_errno($share))); }
$first = curl_init($base . '/cookie/set');
$second = curl_init($base . '/cookie/read');
foreach ([$first, $second] as $client) {
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>2, CURLOPT_SHARE=>$share, CURLOPT_COOKIEFILE=>'']);
    $body = curl_exec($client);
    if ($body === false || curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Тема не получена'); }
    echo $body;
}
curl_setopt($first, CURLOPT_SHARE, null);
curl_setopt($second, CURLOPT_SHARE, null);
unset($first, $second, $client);
unset($share);
Ожидаемый результат
Тема входящего запроса: не выбрана
Тема следующего запроса: blue sky

Полезный результат виден во втором HTTP-ответе. Первый входящий запрос ещё не имел темы, хотя его ответ её установил. Ошибки настройки share используют CURLSH-коды; успех общего кеша не заменяет HTTP-проверки.

Ошибки и следующий шаг. Нельзя разделять cookie-cache между разными посетителями только ради экономии. CURLOPT_COOKIEFILE пустой строкой включает механизм без файла. После передачи easy-клиенты отсоединены от share; curl_share_close в PHP8 не уничтожает объект сам по себе.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Создать общий кеш для нескольких cURL-клиентов одной операции, например использовать одну cookie-сессию партнёра.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
ПараметрыНет. После создания нужно явно выбрать категории общего кеша через share_setopt и присоединить клиентов через CURLOPT_SHARE.
РезультатCurlShareHandle в PHP8+, прежде resource. Это объект кешей, не ответ API и не диспетчер многопоточности.
ГраницаСам share не отправляет запросы и не копирует URL, заголовки или все настройки easyhandle. Обычно multihandle уже ведёт свои кеши; отдельный share нужен, когда требуется общий кеш у отдельных клиентов.
Создаём общий кеш DNS
  1. share_init выдаёт share
  2. share_setopt выбирает DNS
  3. Два easyhandle могут подключиться к этому share

Этот вариант. Это только настройка. Здесь ещё не было DNS-запроса и измерения ускорения.

Создать share и выбрать категориюСамостоятельный пример
<?php
$share = curl_share_init();
var_dump($share instanceof CurlShareHandle);
var_dump(curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS));
Ожидаемый результат
bool(true)
bool(true)

Cookie — небольшое состояние HTTP-клиента для определённого домена/пути. Здесь две клиентские операции относятся к одному учебному пользователю. CURLOPT_COOKIEFILE='' включает cookie-механизм без файла. CURLOPT_COOKIELIST добавляет учебную запись из строки с разделителями \t, CURLINFO_COOKIELIST читает список. Никакой реальный вход или секрет не используется. Cookies и пользовательская сессия.

Этот вариант. Второй клиент видит добавленную первым запись в общей памяти. Правила домена/пути всё ещё решают, к какому запросу она будет отправлена. Не объединяйте таким share сессии разных пользователей.

Увидеть общее состояние двух клиентовСамостоятельный пример
<?php
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) {
    throw new RuntimeException('Share unavailable');
}
$first = curl_init();
$second = curl_init();
if ($first === false || $second === false) { throw new RuntimeException('Client unavailable'); }
foreach ([$first, $second] as $handle) {
    curl_setopt($handle, CURLOPT_SHARE, $share);
    curl_setopt($handle, CURLOPT_COOKIEFILE, '');
}
curl_setopt($first, CURLOPT_COOKIELIST, "example.test\tFALSE\t/\tFALSE\t0\tdemo_session\tdemo-only");
echo count(curl_getinfo($second, CURLINFO_COOKIELIST)), "\n";
Ожидаемый результат
1

Связанные операции: curl_share_setopt; curl_setopt; curl_share_init_persistent.

curl_share_setoptВыбрать или отключить конкретный вид общих данных у обычного sharehandle.

PHP5.5+ · curl

curl_share_setopt(CurlShareHandle $share_handle, int $option, mixed $value): bool

Передать выбор темы между двумя клиентами одного пользователя. Выбирает категорию COOKIE для общего хранения. Каждый easy-клиент отдельно получает CURLOPT_SHARE и включённый cookie engine; URL и тело ответа остаются его собственными.

curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)
  1. Первый клиент посылает GET без Cookie
  2. Сервер отвечает Set-Cookie: theme=blue%20sky
  3. Cookie engine сохраняет значение в общем share
  4. Второй клиент отправляет Cookie и получает тему blue sky

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать выбор темы между двумя клиентами одного пользователяПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) { throw new RuntimeException(curl_share_strerror(curl_share_errno($share))); }
$first = curl_init($base . '/cookie/set');
$second = curl_init($base . '/cookie/read');
foreach ([$first, $second] as $client) {
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>2, CURLOPT_SHARE=>$share, CURLOPT_COOKIEFILE=>'']);
    $body = curl_exec($client);
    if ($body === false || curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Тема не получена'); }
    echo $body;
}
curl_setopt($first, CURLOPT_SHARE, null);
curl_setopt($second, CURLOPT_SHARE, null);
unset($first, $second, $client);
unset($share);
Ожидаемый результат
Тема входящего запроса: не выбрана
Тема следующего запроса: blue sky

Полезный результат виден во втором HTTP-ответе. Первый входящий запрос ещё не имел темы, хотя его ответ её установил. Ошибки настройки share используют CURLSH-коды; успех общего кеша не заменяет HTTP-проверки.

Ошибки и следующий шаг. Нельзя разделять cookie-cache между разными посетителями только ради экономии. CURLOPT_COOKIEFILE пустой строкой включает механизм без файла. После передачи easy-клиенты отсоединены от share; curl_share_close в PHP8 не уничтожает объект сам по себе.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Выбрать или отключить конкретный вид общих данных у обычного sharehandle.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
share_handleОбычный CurlShareHandle. Persistent-объект сюда не подходит: его набор фиксируется при создании.
optionPHP поддерживает CURLSHOPT_SHARE и CURLSHOPT_UNSHARE. Неизвестный option даёт ValueError в PHP8.5.11. Низкоуровневые C-callback опции блокировок не являются автоматически доступными PHP-настройками.
valueCURL_LOCK_DATA_* категория: COOKIE, DNS, SSL_SESSION, CONNECT, PSL — доступность зависит от библиотеки/сборки. Каждую категорию задают отдельно; не OR-маска.
Возвратtrue при успехе, false при отказе libcurl; share_errno даёт числовую причину. Изменение используемого share может вернуть ошибку IN_USE. Сначала настройте его, потом подключайте клиентов.
Настройки задаются до клиентов
  1. Создали share
  2. Включили общий DNS
  3. Отключили DNS до использования
  4. Обе операции сообщают true

Этот вариант. UNSHARE меняет договор кеширования; это не logout на сервере и не команда стереть произвольное внешнее состояние.

Включить и отключить одну категориюСамостоятельный пример
<?php
$share = curl_share_init();
var_dump(curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS));
var_dump(curl_share_setopt($share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_DNS));
Ожидаемый результат
bool(true)
bool(true)

Этот вариант. В этом опыте unset уничтожил последнюю ссылку на easyhandle, который больше никто не хранит. При наличии ссылок в multi/массиве этого недостаточно. CURLOPT_SHARE=null в PHP8.5.11 молча игнорируется, поэтому не используйте его как обещанное отсоединение.

Не менять категории занятого shareСамостоятельный пример
<?php
$share = curl_share_init();
curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
$handle = curl_init();
curl_setopt($handle, CURLOPT_SHARE, $share);
var_dump(curl_share_setopt($share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE));
unset($handle);
var_dump(curl_share_setopt($share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE));
Ожидаемый результат
bool(false)
bool(true)

Этот вариант. Не все неправильные значения дают одинаковый способ отказа. Для штатной конфигурации используйте CURLSHOPT_* и CURL_LOCK_DATA_*.

Различить неизвестную опцию и неверную категориюСамостоятельный пример
<?php
$share = curl_share_init();
try { curl_share_setopt($share, 999999, CURL_LOCK_DATA_DNS); }
catch (ValueError $error) { echo "Invalid option\n"; }
var_dump(curl_share_setopt($share, CURLSHOPT_SHARE, 999999));
Ожидаемый результат
Invalid option
bool(false)

Связанные операции: curl_share_init; curl_share_errno; curl_share_init_persistent.

curl_share_errnoПолучить код последней ошибки настройки share, например отказ изменения занятого кеша.

PHP7.1+; объект/int с PHP8 · curl

curl_share_errno(CurlShareHandle $share_handle): int

Передать выбор темы между двумя клиентами одного пользователя. Читает последний CURLSH-код объекта share. После настройки пример проверяет именно этот код, затем получает реальную тему через два HTTP-запроса. Нулевой код share не доказывает успех HTTP. Имена enum CURLSHE_* из документации libcurl не являются доступными PHP-константами; здесь проверяется описанный код успеха 0.

curl_share_errno($share)
  1. Первый клиент посылает GET без Cookie
  2. Сервер отвечает Set-Cookie: theme=blue%20sky
  3. Cookie engine сохраняет значение в общем share
  4. Второй клиент отправляет Cookie и получает тему blue sky

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать выбор темы между двумя клиентами одного пользователяПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) { throw new RuntimeException(curl_share_strerror(curl_share_errno($share))); }
$shareCode = curl_share_errno($share);
if ($shareCode !== 0) { throw new RuntimeException(curl_share_strerror($shareCode)); }
$first = curl_init($base . '/cookie/set');
$second = curl_init($base . '/cookie/read');
foreach ([$first, $second] as $client) {
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>2, CURLOPT_SHARE=>$share, CURLOPT_COOKIEFILE=>'']);
    $body = curl_exec($client);
    if ($body === false || curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Тема не получена'); }
    echo $body;
}
curl_setopt($first, CURLOPT_SHARE, null);
curl_setopt($second, CURLOPT_SHARE, null);
unset($first, $second, $client);
unset($share);
Ожидаемый результат
Тема входящего запроса: не выбрана
Тема следующего запроса: blue sky

Полезный результат виден во втором HTTP-ответе. Первый входящий запрос ещё не имел темы, хотя его ответ её установил. Ошибки настройки share используют CURLSH-коды; успех общего кеша не заменяет HTTP-проверки.

Ошибки и следующий шаг. Нельзя разделять cookie-cache между разными посетителями только ради экономии. CURLOPT_COOKIEFILE пустой строкой включает механизм без файла. После передачи easy-клиенты отсоединены от share; curl_share_close в PHP8 не уничтожает объект сам по себе.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Получить код последней ошибки настройки share, например отказ изменения занятого кеша.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
share_handleОбычный sharehandle, не multi и не persistent.
ВозвратЦелый CURLSHcode:0 означает успех. С PHP8 больше нет false как результата. Имена C-enum CURLSHE_* в проверенном PHP8.5.11 не экспортированы как PHP-константы — запись CURLSHE_OK вызовет Error.
ОтличиеЭто ошибка общего кеша. Транспортная ошибка отдельного запроса — curl_errno/info_read, ошибка multi — multi_errno. Состояние считывают сразу после интересующей операции.
Состояние обычного share
  1. Создали share
  2. share_errno читает последнее состояние
  3. 0 — ошибки настройки не зарегистрировано

Этот вариант. Нулевой код не сообщает, доступен ли внешний сервис: сеть ещё не использовалась.

Проверить исходное состояниеСамостоятельный пример
<?php
$share = curl_share_init();
echo curl_share_errno($share), "\n";
Ожидаемый результат
0

Этот вариант. Связь bool → код → описание удобна для журнала интеграции. Не сравнивайте этот код с CURLE_* кодами сетевого запроса.

Снять числовую ошибку после отказаСамостоятельный пример
<?php
$share = curl_share_init();
$ok = curl_share_setopt($share, CURLSHOPT_SHARE, 999999);
$code = curl_share_errno($share);
var_dump($ok, $code !== 0);
var_dump(is_string(curl_share_strerror($code)));
Ожидаемый результат
bool(false)
bool(true)
bool(true)

Связанные операции: curl_share_strerror; curl_share_setopt; curl_errno.

curl_share_strerrorПолучить техническое описание числовой ошибки share, чтобы понять отказ настройки.

PHP7.1+ · curl

curl_share_strerror(int $error_code): ?string

Передать выбор темы между двумя клиентами одного пользователя. Даёт описание переданного CURLSH-кода. В share-error.txt записывается реальное описание текущего состояния share, затем выполняется запрос темы. Для успешной настройки это сообщение об отсутствии ошибки; HTTP и CURLE проверяются отдельно.

curl_share_strerror(curl_share_errno($share))
  1. Первый клиент посылает GET без Cookie
  2. Сервер отвечает Set-Cookie: theme=blue%20sky
  3. Cookie engine сохраняет значение в общем share
  4. Второй клиент отправляет Cookie и получает тему blue sky

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать выбор темы между двумя клиентами одного пользователяПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) { throw new RuntimeException(curl_share_strerror(curl_share_errno($share))); }
$description = curl_share_strerror(curl_share_errno($share));
if (file_put_contents(__DIR__ . '/share-error.txt', $description) === false) { throw new RuntimeException('Описание не сохранено'); }
$first = curl_init($base . '/cookie/set');
$second = curl_init($base . '/cookie/read');
foreach ([$first, $second] as $client) {
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>2, CURLOPT_SHARE=>$share, CURLOPT_COOKIEFILE=>'']);
    $body = curl_exec($client);
    if ($body === false || curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Тема не получена'); }
    echo $body;
}
curl_setopt($first, CURLOPT_SHARE, null);
curl_setopt($second, CURLOPT_SHARE, null);
unset($first, $second, $client);
unset($share);
Ожидаемый результат
Тема входящего запроса: не выбрана
Тема следующего запроса: blue sky

Полезный результат виден во втором HTTP-ответе. Первый входящий запрос ещё не имел темы, хотя его ответ её установил. Ошибки настройки share используют CURLSH-коды; успех общего кеша не заменяет HTTP-проверки.

Ошибки и следующий шаг. Нельзя разделять cookie-cache между разными посетителями только ради экономии. CURLOPT_COOKIEFILE пустой строкой включает механизм без файла. После передачи easy-клиенты отсоединены от share; curl_share_close в PHP8 не уничтожает объект сам по себе.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Получить техническое описание числовой ошибки share, чтобы понять отказ настройки.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
error_codeЧисло CURLSHcode из share_errno; это отдельное семейство от CURLM_*/CURLE_*.
ВозвратОписание или null по сигнатуре. В проверенной libcurl8.22 неизвестное число возвращает строку CURLSHcode unknown. Не используйте is_string как проверку, что код известен.
Для интерфейсаОписание рассчитано на разработчика; бизнес-логика проверяет числовой успех/отказ и показывает пользователю понятный текст.
Код0 получает подпись
  1. Передали числовой успех0
  2. Функция вернула техническое описание
  3. Решение об успехе принимается по коду

Этот вариант. Используется0, потому что libcurl C-имя CURLSHE_OK не экспортировано в PHP этой сборки.

Описание обычного кодаСамостоятельный пример
<?php
$text = curl_share_strerror(0);
var_dump(is_string($text) && $text !== '');
Ожидаемый результат
bool(true)

Этот вариант. Не фиксируем английскую фразу как ожидаемый договор: её формулировка может зависеть от libcurl.

Описание реально полученного отказаСамостоятельный пример
<?php
$share = curl_share_init();
curl_share_setopt($share, CURLSHOPT_SHARE, 999999);
$code = curl_share_errno($share);
$text = curl_share_strerror($code);
var_dump($code !== 0, is_string($text));
Ожидаемый результат
bool(true)
bool(true)

Связанные операции: curl_share_errno; curl_multi_strerror; curl_strerror.

curl_share_closeПонять старый cleanup-код: в PHP8 этот вызов ничего не закрывает, а с PHP8.5 помечен deprecated.

PHP5.5+; no-op8.0, deprecated8.5 · curl

curl_share_close(CurlShareHandle $share_handle): void

Передать выбор темы между двумя клиентами одного пользователя. Историческое закрытие ничего не делает с PHP8.0 и устарело с PHP8.5. После отсоединения easy-клиентов современный код освобождает ссылки; уже полученная тема остаётся строкой.

unset($share)
  1. Первый клиент посылает GET без Cookie
  2. Сервер отвечает Set-Cookie: theme=blue%20sky
  3. Cookie engine сохраняет значение в общем share
  4. Второй клиент отправляет Cookie и получает тему blue sky

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Передать выбор темы между двумя клиентами одного пользователяПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$share = curl_share_init();
if (!curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)) { throw new RuntimeException(curl_share_strerror(curl_share_errno($share))); }
$first = curl_init($base . '/cookie/set');
$second = curl_init($base . '/cookie/read');
foreach ([$first, $second] as $client) {
    curl_setopt_array($client, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>2, CURLOPT_SHARE=>$share, CURLOPT_COOKIEFILE=>'']);
    $body = curl_exec($client);
    if ($body === false || curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Тема не получена'); }
    echo $body;
}
curl_setopt($first, CURLOPT_SHARE, null);
curl_setopt($second, CURLOPT_SHARE, null);
unset($first, $second, $client);
unset($share);
Ожидаемый результат
Тема входящего запроса: не выбрана
Тема следующего запроса: blue sky

Полезный результат виден во втором HTTP-ответе. Первый входящий запрос ещё не имел темы, хотя его ответ её установил. Ошибки настройки share используют CURLSH-коды; успех общего кеша не заменяет HTTP-проверки.

Ошибки и следующий шаг. Нельзя разделять cookie-cache между разными посетителями только ради экономии. CURLOPT_COOKIEFILE пустой строкой включает механизм без файла. После передачи easy-клиенты отсоединены от share; curl_share_close в PHP8 не уничтожает объект сам по себе.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Понять старый cleanup-код: в PHP8 этот вызов ничего не закрывает, а с PHP8.5 помечен deprecated.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
share_handleОбычный CurlShareHandle; persistent имеет другой класс.
ПоведениеДо PHP8 закрывал resource. Начиная с PHP8 — no-op; с PHP8.5 вызывает E_DEPRECATED. Полезного возвращаемого значения нет.
АльтернативаУправляйте ссылками на объекты: easyhandle удерживает share. Освобождение последней переменной share не уничтожает его, пока клиенты ещё используют объект. Persistent-кеш живёт по отдельным правилам процесса.
В старом коде close не меняет share
  1. Создали объект share
  2. Вызвали устаревший close; диагностируем deprecated
  3. Тот же объект ещё принимает настройку

Первый пример специально воспроизводит устаревший вызов на PHP8.5+. set_error_handler задаёт временную функцию обработки; она считает только E_DEPRECATED, finally восстанавливает прежнюю. use (&$deprecated) даёт этой функции доступ к тому же внешнему счётчику, а ++ увеличивает его на1. Это демонстрация миграции, а не совет подавлять предупреждения на сайте. Захват переменной замыканием.

Этот вариант. Поведение deprecated проверено именно на PHP8.5.11. На PHP8.2–8.4 no-op уже есть, но такого предупреждения ещё нет.

Проверить no-op при миграции на PHP8.5Самостоятельный пример
<?php
$share = curl_share_init();
$deprecated = 0;
set_error_handler(function ($level, $message) use (&$deprecated) {
    if ($level !== E_DEPRECATED) { return false; }
    $deprecated++;
    return true;
});
try { curl_share_close($share); }
finally { restore_error_handler(); }
echo $deprecated, "\n";
var_dump(curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS));
Ожидаемый результат
1
bool(true)

WeakReference ниже позволяет наблюдать, жив ли объект, не удерживая его. $weak->get() возвращает объект или null. Это диагностический опыт жизненного цикла, в обычном приложении WeakReference для cURL не требуется.

Этот вариант. После удаления вашей переменной клиент ещё удерживает share. Только после освобождения последнего easyhandle исчезает последняя сильная ссылка в этом примере.

Увидеть, кто удерживает общий кешСамостоятельный пример
<?php
$share = curl_share_init();
$weak = WeakReference::create($share);
$handle = curl_init();
curl_setopt($handle, CURLOPT_SHARE, $share);
unset($share);
var_dump($weak->get() instanceof CurlShareHandle);
unset($handle);
var_dump($weak->get());
Ожидаемый результат
bool(true)
NULL

Связанные операции: curl_share_init; curl_share_init_persistent.

curl_share_init_persistentИспользовать согласованные кеши DNS/TLS/соединений между запросами PHP внутри одного живущего процесса.

PHP8.5+ · curl

curl_share_init_persistent(array $share_options): CurlSharePersistentHandle

Применить допустимый общий кеш без объединения cookies. PHP8.5 создаёт постоянный share по набору допустимых категорий. Это механизм процесса PHP; пользовательские cookies для него не допускаются.

curl_share_init_persistent([CURL_LOCK_DATA_DNS])
  1. Выбран только DNS-cache
  2. Новый easy-клиент подключён к share
  3. Локальный HTTP возвращает строку товара
  4. Опыт не измеряет межзапросное кеширование

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Применить допустимый общий кеш без объединения cookiesПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$share = curl_share_init_persistent([CURL_LOCK_DATA_DNS]);
$client = curl_init($base . '/product?id=1');
curl_setopt_array($client, [CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 2, CURLOPT_CONNECTTIMEOUT => 1]);
curl_setopt($client, CURLOPT_SHARE, $share);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
Ожидаемый результат
Молоток — 8 шт.

Здесь адрес уже числовой, поэтому реального DNS lookup нет. Пример проверяет совместимость API и обычную передачу с присоединённым постоянным share, сохраняя честную границу наблюдения.

Ошибки и следующий шаг. Требуется PHP8.5+. Один CLI-запуск не доказывает reuse между HTTP-запросами одного worker. Список разрешённых кешей, исключения для COOKIE и различие CurlShareHandle/CurlSharePersistentHandle сохранены в контракте ниже.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Использовать согласованные кеши DNS/TLS/соединений между запросами PHP внутри одного живущего процесса.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
share_optionsНепустой массив int-констант: DNS, SSL_SESSION, CONNECT, PSL. Повторы удаляются, порядок не определяет отдельный кеш; тот же набор повторно использует underlying share.
ЗапрещеноCOOKIE вызывает ValueError: cookies разных пользователей нельзя смешивать между PHP-запросами. Пустой массив и неизвестная категория также ValueError; неподходящий тип значения — TypeError.
Точность типовManual говорит о TypeError для любого не-int. В tagged PHP8.5.11 numeric-string/float могут преобразовываться через zval_try_get_long; null доходит до ValueError. Учебный договор намеренно строгий: передавать только именованные int-константы, не рассчитывать на coercion.
Возврат / настройкаCurlSharePersistentHandle с readonly array options. Он подключается easy-клиенту через CURLOPT_SHARE. share_setopt/share_errno/share_close принимают обычный класс и отклоняют persistent с TypeError.
Жизнь кешаПовторное использование относится к процессу/его внутреннему хранилищу, не ко всем воркерам/серверам сразу. В CLI-процессе на один запуск выигрыш между запусками отсутствует. Одинаковый набор не обещает одинаковый PHP-объект через ===.
Дополнительный отказЕсли libcurl не может включить допустимую категорию, PHP8.5.11 бросает Exception; наличие константы не гарантирует конкретную TLS/PSL поддержку сборки.
Одни категории — один договор постоянного кеша
  1. Передали DNS+CONNECT с повтором DNS
  2. PHP нормализует набор
  3. Получаем объект options с2категориями
  4. Другой порядок использует тот же набор кешей

Этот вариант. Проверено два разных PHP-объекта с одинаковыми нормализованными options. Реальный reuse underlying share подтверждён source; это не замер повторного TCP-соединения.

Нормализовать набор кешей на PHP8.5+Самостоятельный пример
<?php
$first = curl_share_init_persistent([CURL_LOCK_DATA_CONNECT, CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_DNS]);
$second = curl_share_init_persistent([CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_CONNECT]);
echo count($first->options), "\n";
var_dump($first->options === $second->options);
var_dump($first === $second);
Ожидаемый результат
2
bool(true)
bool(false)

Этот вариант. stdClass здесь только показывает неподходящий элемент. Пользовательские данные не должны выбирать произвольный кеш или объект.

Отвергнуть cookie-кеш и неверный наборСамостоятельный пример
<?php
foreach ([[], [CURL_LOCK_DATA_COOKIE], [999999]] as $options) {
    try { curl_share_init_persistent($options); }
    catch (ValueError $error) { echo "Invalid set\n"; }
}
try { curl_share_init_persistent([new stdClass()]); }
catch (TypeError $error) { echo "Invalid type\n"; }
Ожидаемый результат
Invalid set
Invalid set
Invalid set
Invalid type

Этот вариант. Чтобы получить другой набор, вызовите persistent-фабрику с другим разрешённым массивом. Глобально чистить чужие пользовательские сессии через него не требуется: cookies специально исключены.

Не менять фиксированный договор после созданияСамостоятельный пример
<?php
$share = curl_share_init_persistent([CURL_LOCK_DATA_DNS]);
try { $share->options = []; }
catch (Error $error) { echo "Readonly options\n"; }
try { curl_share_setopt($share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); }
catch (TypeError $error) { echo "Different handle type\n"; }
Ожидаемый результат
Readonly options
Different handle type

Связанные операции: curl_share_init; curl_share_setopt; curl_setopt.

curl_setoptНастроить одну часть будущего запроса: адрес, время ожидания, тело или обработчик ответа.

PHP 4.0.2+ · curl

curl_setopt(CurlHandle $handle, int $option, mixed $value): bool

Прочитать остаток Молотка у своего HTTP-сервера. Настраивает одну опцию клиента. RETURNTRANSFER=true меняет способ получения тела: curl_exec возвращает текст вместо немедленного вывода.

curl_setopt($client, CURLOPT_RETURNTRANSFER, true)
  1. PHP-клиент → GET /product?id=1 → 127.0.0.1:8791
  2. server.php выбирает Молоток со stock8
  3. Сервер → HTTP200, Content-Type text/plain, тело «Молоток — 8 шт.»
  4. Клиент проверяет транспорт и статус, затем выводит тело

В архиве есть server.php с известным каталогом, base.php и этот клиент example.php. В первом терминале запустите php -S 127.0.0.1:8791 server.php, во втором — php example.php. Полная подготовка и первые два файла.

Прочитать остаток Молотка у своего HTTP-сервераПример для указанного окружения
<?php
declare(strict_types=1);

require __DIR__ . '/base.php';
$client = curl_init($base . '/product?id=1');
if ($client === false) { throw new RuntimeException('cURL не создал клиент'); }
curl_setopt($client, CURLOPT_RETURNTRANSFER, true);
curl_setopt($client, CURLOPT_TIMEOUT, 2);
curl_setopt($client, CURLOPT_CONNECTTIMEOUT, 1);
$body = curl_exec($client);
if ($body === false) { throw new RuntimeException('Нет ответа: '.curl_error($client)); }
if (curl_getinfo($client, CURLINFO_RESPONSE_CODE) !== 200) { throw new RuntimeException('Сервис отклонил запрос'); }
echo $body;
Ожидаемый результат
Молоток — 8 шт.

Серверный каталог полностью задан в приложенном server.php. $client — объект настройки; $body — полученный текст. Это разные значения. Тело ответа можно вывести, сохранить или разобрать по согласованному формату.

Ошибки и следующий шаг. Для неизвестного id99 сервер возвращает 404 и JSON с причиной. Для пустого успешного ответа используйте === false, не if (!$body). Таймаут сети и HTTP-ошибка требуют разных сообщений. Опции устанавливаются до exec; их ошибки тоже нужно учитывать в библиотечном коде.

Примените ту же проверку передачи в самостоятельном расчёте цены с успешным ответом, HTTP 409 и поддельным типом. Он показывает, как полученные байты превращаются в полезное сообщение, и содержит собственный сервер.

Полный официальный контракт и дополнительные варианты. Далее сохранены все параметры, типы результатов, версии и ограничения этой операции. Сначала прочитайте пояснение соответствующего следующего примера.

Настроить одну часть будущего запроса: адрес, время ожидания, тело или обработчик ответа.

cURL выполняет запрос от сервера PHP к другому адресу. $handle хранит состояние клиента, а не ответ. curl_init создаёт это состояние, curl_setopt задаёт настройку, curl_exec запускает передачу. Скобки содержат аргументы; = сохраняет результат. === false отличает отказ от пустой строки или строки0.

В массивах ключ => значение связывает настройку с её значением. if выбирает действие по условию; try/finally гарантирует обычную уборку при исключении. Как устроен вызов функции, запрос и HTTP-ответ и JSON и массивы объясняют эти понятия отдельно.

Часть вызоваДоговор и границы
handleОбъект клиента от curl_init(), ещё не ответ сервера.
optionИменованная CURLOPT_* настройка; для диагностики исходящих заголовков PHP также поддерживает CURLINFO_HEADER_OUT как специальную опцию.
valueЗначение того типа, который требует выбранная настройка. Список ниже не подменяет конкретный договор.
Результатtrue — настройка принята; false — отказ. Вызов сам не выполняет запрос.
ОшибкиValueError для неизвестной option (PHP 8.0+); отдельные значения/callback проверяются своим договором. HTTP-ошибок здесь ещё нет.
Конкретный первый вызов
  1. curl_init → $handle
  2. CURLOPT_URL выбирает настройку адреса
  3. Строка http://127.0.0.1:8781/order/42 записывается в handle
  4. true → можно перейти к другим настройкам
  5. Сеть запустится только при curl_exec

Сначала настроим адрес учебного сервиса. curl_setopt ещё не соединяется с сервером: запрос запускается отдельным curl_exec. Поэтому пример безопасно показывает этап конфигурации даже без запущенного сервера.

Этот вариант. CURLOPT_URL — целочисленный ключ настройки, а третьим аргументом передаётся адрес-строка. Handle хранит настройки. Отсутствие curl_exec здесь намеренно: работа с сетью не выполняется.

Задать адрес без отправки запросаСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) throw new RuntimeException('Не создан клиент');
$configured = curl_setopt($handle, CURLOPT_URL, 'http://127.0.0.1:8781/order/42');
echo $configured ? "Адрес задан; запрос ещё не отправлен\n" : "Настройка отклонена\n";
Ожидаемый результат
Адрес задан; запрос ещё не отправлен

Этот вариант. При вызове $handle получает объект клиента, $milliseconds — 1500. min ограничивает фазу соединения, второй вызов ограничивает весь обмен. Общий лимит включает фазу соединения, это не сумма 500+1500. DNS/системный резолвер имеют платформенные нюансы; значения не являются обещанием точности таймера.

Повторно использовать политику таймаутовСамостоятельный пример
<?php
declare(strict_types=1);

function configureTimeouts(CurlHandle $handle, int $milliseconds): void {
    if ($milliseconds < 1) throw new InvalidArgumentException('Нужен положительный лимит');
    if (!curl_setopt($handle, CURLOPT_CONNECTTIMEOUT_MS, min(500, $milliseconds))
        || !curl_setopt($handle, CURLOPT_TIMEOUT_MS, $milliseconds)) {
        throw new RuntimeException('Таймауты не настроены');
    }
}
$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
configureTimeouts($handle, 1500);
echo "Соединение: до 500 ms; весь обмен: до 1500 ms\n";
Ожидаемый результат
Соединение: до 500 ms; весь обмен: до 1500 ms

Этот вариант. PHP 8+ бросает ValueError для неизвестного ключа. Это ошибка конфигурации программы, её не следует повторять как временный сетевой отказ.

Не проглотить ошибочное имя настройкиСамостоятельный пример
<?php
declare(strict_types=1);

$handle = curl_init();
if ($handle === false) throw new RuntimeException('Нет клиента');
try {
    curl_setopt($handle, 0, 'value');
} catch (ValueError $error) {
    echo "Неизвестная настройка\n";
}
Ожидаемый результат
Неизвестная настройка

У опций разные ожидаемые значения: CURLOPT_URL — строка; CURLOPT_TIMEOUT_MS — целое число миллисекунд; CURLOPT_FOLLOWLOCATION — bool либо специальные CURLFOLLOW_* в новых версиях; CURLOPT_HTTPHEADER — список строк; callback-опции — вызываемая функция; файловые опции — ресурс. Общий тип mixed не означает, что любой тип допустим для любой настройки. Некоторые преобразования делает PHP, но в учебном и рабочем коде передавайте документированный тип.

Параметр handle с PHP 8.0 — объект CurlHandle, прежде был ресурс. У неизвестной option с PHP 8.0 ValueError; старое поведение с игнорированием/предупреждением использовать нельзя. Неверный callback или несовместимый тип значения также может дать TypeError/ValueError. Возврат false означает отказ установить поддерживаемую настройку, а не сетевой HTTP-статус.

Настройки одного handle сохраняются между передачами до изменения/reset. Переключение метода, тела, callback и заголовков взаимосвязано: изменение CURLOPT_CUSTOMREQUEST меняет текст метода, но не превращает тело в нужный формат. Для независимых запросов проще отдельный клиент либо явный полный сброс/перенастройка. Пропущенные поля не возвращаются к значениям по умолчанию сами.

Подробный тип, единицы, значение по умолчанию, версии и взаимодействия каждого ключа приведены в полном справочнике констант.

Связанные операции: curl_setopt_array; curl_exec; curl_reset; curl_getinfo.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.