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

Дерево руководства
Глава 114 · От первого запроса до полного справочника
cURL: HTTP-интеграции, файлы, параллельные запросы и полный справочник
От одного понятного запроса до multipart, таймаутов, multi и общих кешей: все функции, классы, методы, параметры и константы расширения cURL.
Как читать справочник после первого запроса
От данных заказа до результата интеграции
Короткий вызов curl_exec соединяет несколько разных этапов.
- 1Заказ 42 в массиве PHP↓
Выбираем форму, JSON или multipart по договору API.
- 2CurlHandle и настройки↓
Адрес, тело, заголовки, TLS и таймауты описывают запрос.
- 3Передача и HTTP-ответ↓
curl_exec запускает сеть; код HTTP проверяется отдельно от ошибки транспорта.
- 4Проверенный результат
Разбираем формат, проверяем поля и только потом продолжаем заказ.
Успешная передача ещё не означает успешную бизнес-операцию. Повтор после обрыва может продублировать заказ.
Начните с двух маленьких PHP-файлов: клиент получит строку товара из настоящего ответа. Затем сравните тела формы, JSON и multipart и рассчитайте предложение цены. Здесь сохранён полный справочник cURL: настройка, все семейства констант, объекты, функции, ограничения и версии.
- curl_init: объект настроек
- curl_setopt: URL, тело, заголовки, сроки
- curl_exec: передача и тело
- curl_getinfo / curl_error: разные виды результата
Объект клиента можно представить как отдельную карточку настроек и состояния запроса; само наличие такой карточки не означает отправки. Аналогия не описывает соединения и кеши libcurl: reset сбрасывает опции, но не обязан стирать cookies, кеш DNS и живые соединения. Копирование конфигурации также не создаёт независимую бизнес-сессию.
Два запроса: сначала понять цикл диспетчера
Когда нужны два товара, multi управляет несколькими easy-клиентами. Первый задаёт id=1, второй id=2. Диспетчер продвигает передачи и ждёт готовности; приложение отдельно проверяет транспорт каждой передачи, HTTP-статус каждого ответа и его тело. Локальный сервер может обслужить их последовательно: этот опыт не является измерением ускорения.
- CurlHandle №1: /product?id=1
- CurlHandle №2: /product?id=2
- finishTransfers: exec → сообщения → ожидание select → следующий шаг
- Вывод выбранного порядка: Молоток 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-расширение устанавливаются и проверяются отдельно.
- Браузер → наш PHP: оформить заказ42
- Наш PHP → API доставки: подготовить отправление
- API → PHP: статус и данные ответа
- 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; сначала найдите используемый интерпретатор и его конфигурацию, затем подключайте подходящее расширение.
- Какой PHP запускает приложение?
- php --ini и php -m для CLI
- Для веб-процесса проверяем его SAPI/config
- После настройки перезапускаем нужный процесс
Этот вариант. Таков результат проверенной сборки PHP8.5.11/libcurl8.22.0. В другой сборке false — диагностический результат, а не повод отключить проверки сертификата. php_ini_loaded_file показывает путь локальной конфигурации; не публикуйте подробную диагностику сервера для посетителей.
<?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 предоставляет функции curl_*
- libcurl реализует протоколы и опции
- TLS выполняет выбранный backend
- Проверяем все уровни нужной возможности
| Ветка PHP | Минимум libcurl из официального руководства |
|---|---|
| Ранее PHP7.3 | 7.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; эти числа описывают стенд, не объявляют его единственно возможной конфигурацией.
Установка: готовый пакет и сборка из исходников
- PHP нужной архитектуры/ABI
- Расширение curl из того же комплекта
- Зависимые библиотеки доступны процессу
- Проверка 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
- Сервис предъявляет сертификат
- Клиент проверяет доверенную цепочку и имя
- Настроенный CA bundle участвует в проверке
- Только затем передаём чувствительные данные
| Настройка | Договор |
|---|---|
| curl.cainfo | string, по умолчанию 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.
<?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
- Один запрос → CurlHandle
- Координация запросов → CurlMultiHandle
- Обмен кэшами → CurlShareHandle
- С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 имеет другое назначение, не переносите правило механически.
<?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.
- curl_init → $handle
- curl_setopt($handle, ...) меняет настройки
- curl_exec($handle) использует их
- curl_getinfo($handle, ...) читает сведения
Этот вариант. Два имени переменных указывают на один объект. Отдельную конфигурацию создают curl_copy_handle или clone, а не обычным присваиванием.
<?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-ошибок, а структура данных — после декодирования.
- PHP: order=42, city=Perm
- Форма → order=42&city=Perm; JSON → объект
- curl_exec доставляет байты в выбранный endpoint
- Ответ → 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.
<?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
Выбор подхода, стоимость и отказ зависимости
- Транспорт: curl_exec !== false
- HTTP: ожидаемый код, не просто любой200
- Формат: JSON/файл по договору
- Предметная область: заказ42 действительно принят
| Задача | Подход |
|---|---|
| Один небольшой запрос | curl_exec с timeout и проверкой ответа. |
| Несколько независимых источников | curl_multi_exec с ограничением параллельности и обработкой каждой завершённой передачи. |
| Повторные обращения | Переиспользовать клиент осознанно; кэши могут ускорить соединение, но cookies/авторизация не должны смешивать пользователей. |
| Вложение на диске | CURLFile::__construct; заранее читать всё в память не требуется. |
| Небольшой отчёт уже в переменной | CURLStringFile::__construct. |
| Простой краткий HTTP read | PHP 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; эти случаи не заменяют друг друга.
- Могу показать место выбора формата
- Знаю, где происходит сеть
- Различаю transport, HTTP и данные
- Могу обработать отказ без второго заказа
Этот вариант. Это локальная проверка соглашений форматов, не замена 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 ни один байт не уйдёт к партнёру.
- $file->name = storage/act.txt
- $file->mime = text/plain; postname = act-42.txt
- POSTFIELDS[document] = $file
- PHP-приёмник: $_FILES[document][name] = act-42.txt
| Свойство | Смысл |
|---|---|
| public string name = "" | Исходный путь. Конструктор получает его первым аргументом. |
| public string mime = "" | Заданный тип; пустой → application/octet-stream при передаче. |
| public string postname = "" | Заданное внешнее имя; пустой → name при передаче. |
Этот вариант. Здесь свойства отображают конфигурацию. Изменяйте её до установки POSTFIELDS. 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 без промежуточной записи на диск. Это экономит отдельную операцию с диском, но не память под сам отчёт.
- $data содержит байты A, NUL, B
- CURLStringFile(data, payload.bin)
- Свойства data/postname/mime
- 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.
- Ваш PHP-код создаёт два easyhandle
- Multi хранит оба клиента
- exec продвигает ввод/вывод; select ожидает активность
- 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-клиентами. Он не копирует автоматически всю конфигурацию и не запускает запросы параллельно.
- Создать share
- Выбрать COOKIE для одного пользователя
- Подключить к первому и второму easyhandle
- 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. Кеш не становится общей базой всех процессов; перезапуск воркера заканчивает его жизнь.
- Запрос A выбирает набор DNS+CONNECT
- Underlying share хранится в процессе
- Запрос B того же процесса выбирает тот же набор
- Повторно используется кеш, но не 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. Это учебное окружение, не установка публичного веб-сервера.
- Создать 3 клиента с метками stock/price/missing
- exec/select продвигают запросы, максимум 2 соединения
- info_read → CURLE_OK отдельно от HTTP 200/404
- Проверить JSON/типы цены и остатка; собрать карточку
Этот вариант. Контекст: включён curl, запущен приложенный локальный fixture-сервер, PHPMAN_CURL_TEST_BASE задаёт его адрес. Общий CLI-check выполняет lint; отдельный evidence-стенд реально выполняет запросы и проверяет этот вывод. Отключение proxy относится к loopback-тесту. Внешние адреса не подставляются, авторизация/ретраи/политика загрузки больших тел здесь не реализованы.
<?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-файла на диске.
- Первый клиент получает Set-Cookie
- libcurl сохраняет cookie в обычном share
- Второй клиент использует тот же share и домен
- Сервер видит demo_session=demo-only
Этот вариант. Это реальный loopback HTTP-тест, а не обращение к аккаунту или внешнему сервису. До кода нужен приложенный fixture-server.py, запущенный Python 3, и PHPMAN_CURL_TEST_BASE по инструкции предыдущего раздела. Для нового пользователя создают отдельный share; persistent-API cookies не принимает.
<?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') | Проверить существование имени до обращения к константе; строка здесь необходима. |
- Имя CURLOPT_TIMEOUT_MS передаётся строкой в defined
- true → можно использовать именованный ключ
- curl_setopt настраивает handle
- Передача начнётся только отдельным 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:// запускают принципиально разные действия. Следующий пример только настраивает будущий запрос и никому не подключается.
- https://api.example.test/catalog — явная схема
- PROTOCOLS_STR = https ограничивает начальный адрес
- REDIR_PROTOCOLS_STR = https ограничивает переходы
- FOLLOWLOCATION = false оставляет redirect решением приложения
Этот вариант. Пример рассчитан на PHP 8.3+ с соответствующим libcurl. В нём нет curl_exec. Даже разрешённый HTTPS может вести на внутренний IP: для адреса от пользователя дополнительно нужна политика адресатов, DNS/IP, proxy и redirect. Список протоколов не является полной защитой SSRF.
<?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 ограничить отдельно. Значение/результат: int-маска CURLPROTO_*. По умолчанию: все поддерживаемые, кроме file при open_basedir. Версии: Доступно с libcurl 7.19.4 and deprecated as of libcurl 7.85.0. Native API: libcurl 7.19.4. |
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. |
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. |
CURLPROTO_ALLТип самой константы: int | Историческая маска всех перечисленных в старом bitmask API протоколов. В современном libcurl она уже не включает все новые протоколы; с 7.85.0 предпочтительны PROTOCOLS_STR/REDIR_PROTOCOLS_STR. Для недоверенного URL не выбирать «всё». Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_DICTТип самой константы: int | Бит DICT — сетевых словарных запросов. Наличие имени константы не доказывает поддержку протокола сборкой. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_FILEТип самой константы: int | Бит file:// — доступа к локальным файлам. Не включать в клиент внешних URL: разрешённая схема может открыть локальный ресурс. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_FTPТип самой константы: int | Бит обычного FTP. FTP+явный TLS настраивается через USE_SSL; это не то же самое, что разрешить схему ftps://. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_FTPSТип самой константы: int | Бит FTPS — FTP с TLS, включая схему ftps://. Это не SFTP. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_GOPHERТип самой константы: int | Бит Gopher. Его разрешение не требуется обычному HTTP API клиенту. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.2. |
CURLPROTO_HTTPТип самой константы: int | Бит http://, без TLS. В учебном примере допустим loopback; конфиденциальные внешние запросы требуют HTTPS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_HTTPSТип самой константы: int | Бит https:// — HTTP через TLS. Проверка сертификата/имени и разрешение конкретного адреса всё равно обязательны. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_IMAPТип самой константы: int | Бит IMAP — чтения/управления почтовым ящиком; явный STARTTLS настраивается отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_IMAPSТип самой константы: int | Бит IMAPS — IMAP через TLS с начала соединения. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_LDAPТип самой константы: int | Бит LDAP — запросов к каталогу; транспортная защита зависит от отдельной настройки. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_LDAPSТип самой константы: int | Бит LDAPS — LDAP через TLS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_MQTTТип самой константы: int | Бит MQTT — обмена с broker. Не означает поддержку всех MQTT extensions или любого способа аутентификации. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.71.0. |
CURLPROTO_POP3Тип самой константы: int | Бит POP3 — получения почты; обычная схема сама TLS не требует. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_POP3SТип самой константы: int | Бит POP3 через TLS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_RTMPТип самой константы: int | Исторический бит RTMP — мультимедийного протокола; применимость зависит от наличия соответствующего backend в сборке. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.0. |
CURLPROTO_RTMPEТип самой константы: int | Исторический бит RTMP с вариантом шифрования E; это не TLS и не синоним HTTPS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.0. |
CURLPROTO_RTMPSТип самой константы: int | Исторический бит RTMP через TLS; проверить фактический протокол в runtime. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.0. |
CURLPROTO_RTMPTТип самой константы: int | Исторический бит RTMP, туннелируемого через HTTP. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.0. |
CURLPROTO_RTMPTEТип самой константы: int | Исторический бит туннелируемого через HTTP RTMP с шифрованием E. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.0. |
CURLPROTO_RTMPTSТип самой константы: int | Исторический бит RTMP в защищённом TLS HTTP-туннеле. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.0. |
CURLPROTO_RTSPТип самой константы: int | Бит RTSP — управления медиасессией. Передача самих медиаданных и RTSP-команды различаются. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_SCPТип самой константы: int | Бит SCP — копирования через SSH. Не смешивать с FTP/FTPS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_SFTPТип самой константы: int | Бит SFTP — файлового протокола SSH; проверка SSH host key и ключа клиента задаются отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_SMBТип самой константы: int | Исторический бит SMB доступа к сетевым файлам; поддержка зависит от сборки. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0. |
CURLPROTO_SMBSТип самой константы: int | Исторический бит SMB через TLS. Это отдельная схема libcurl, не обещание поддержки всех современных Windows SMB режимов. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0. |
CURLPROTO_SMTPТип самой константы: int | Бит SMTP — отправки почты серверу; STARTTLS, получатели и авторизация настраиваются отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_SMTPSТип самой константы: int | Бит SMTP через TLS с начала соединения. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURLPROTO_TELNETТип самой константы: int | Бит Telnet; протокол не предоставляет шифрование сам по себе. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
CURLPROTO_TFTPТип самой константы: int | Бит TFTP — простой файловой передачи по UDP; это не FTP и не защищённое хранилище. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.4. |
HTTP: метод, тело, заголовки, версия и redirect
Метод описывает действие, тело содержит данные, заголовки описывают представление и условия. Это связанные настройки: POSTFIELDS выбирает POST, NOBODY — запрос без тела ответа, CUSTOMREQUEST меняет текст метода. Переход на другой URL может также менять метод и политику передачи credentials. Условный запрос по времени/диапазону требует поддержки сервера.
Один и тот же товар можно отправить как форму или JSON, но сервер должен знать, какой формат он получает. Сначала приготовим байты и посмотрим их, затем установим тело. POSTFIELDS со строкой не кодирует данные за вас. POSTFIELDS с массивом выбирает multipart; это третий формат, рассмотренный в карточках файлов.
- Массив sku=A42, quantity=2
- json_encode → текст JSON
- HTTPHEADER → application/json
- POSTFIELDS → те же подготовленные байты
Этот вариант. [] создаёт массив; => связывает ключ со значением. http_build_query и json_encode возвращают разные строки из одних данных. Content-Type описывает именно отправленные байты. Здесь POSTFIELDS сам выбирает POST; CUSTOMREQUEST для обычного POST не нужен.
<?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. |
CURLFOLLOW_FIRSTONLYТип самой константы: int | Применять CUSTOMREQUEST только к первому запросу, затем выбирать метод по обычным правилам redirect. Это отличается от постоянного ALL. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.5.0 и libcurl 8.13.0. |
CURLFOLLOW_OBEYCODEТип самой константы: int | Следовать redirect, подчиняя custom method HTTP-коду: для соответствующих 301/302/303 может применяться GET. POSTREDIR может уточнять сохранение POST. Состояние метода и отправка тела остаются связанными. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.5.0 и libcurl 8.13.0. |
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. |
CURLHEADER_UNIFIEDТип самой константы: int | Один набор HTTPHEADER для origin и proxy, PROXYHEADER игнорируется. Старый default до libcurl 7.42.1; осторожно с секретами origin при передаче прокси. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.37.0. |
CURLMIMEOPT_FORMESCAPEТип самой константы: int | Для multipart HTTP экранировать имена полей/файлов обратным слешем, как старые реализации, вместо современного percent-encoding кавычек/CR/LF. До libcurl 7.81.0 применялся старый способ. Флаг нужен лишь для согласованного legacy-сервера; не меняет кодировку тела файла. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.3.0 и libcurl 7.81.0 |
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 не включать автоматически; фактическое значение доступно в Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
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. |
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. |
CURLOPT_FAILONERRORТип самой константы: int | Преобразовать HTTP>=400 в Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
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. |
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. |
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. |
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. |
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 существующего соединения может привести к иной версии, чем запрошено; проверять Значение/результат: int CURL_HTTP_VERSION_*. По умолчанию: NONE с8.13;2TLS с7.62; ранее1_1. Версии: Доступно с libcurl 7.9.1. Native API: libcurl 7.9.1. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLOPT_REFERERТип самой константы: int | Исходящий Referer HTTP header; последняя строка заменяет предыдущую. AUTOREFERER может менять его при redirect. Не помещать сюда полный URL с секретными query-параметрами; это заявление клиента, не доказательство источника запроса. Значение/результат: string|null. По умолчанию: null. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
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. |
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. |
CURLOPT_TIMECONDITIONТип самой константы: int | Условие по времени изменения ресурса, которое задаёт TIMEVALUE/TIMEVALUE_LARGE: IFMODSINCE либо IFUNMODSINCE, NONE отключает. Сервер может не предоставить время/не поддержать условие; смотрите HTTP-статус и Значение/результат: int: CURL_TIMECOND_*. По умолчанию: CURL_TIMECOND_NONE в современном libcurl. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
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. |
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. |
CURL_HTTP_VERSION_1_0Тип самой константы: int | Запрашивать HTTP/1.0. Не включает TLS и не является настройкой версии PHP. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_HTTP_VERSION_1_1Тип самой константы: int | Запрашивать HTTP/1.1; HTTP/2 multiplexing при таком выборе не является целью запроса. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_HTTP_VERSION_2Тип самой константы: int | Современное имя значения 2_0: попытаться HTTP/2 с допустимым откатом к HTTP/1.1 при невозможности согласования. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.43.0 |
CURL_HTTP_VERSION_2TLSТип самой константы: int | Пробовать HTTP/2 только для HTTPS, с откатом к 1.1. Для незашифрованного HTTP используется 1.1. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.47.0 |
CURL_HTTP_VERSION_2_0Тип самой константы: int | Попытаться HTTP/2; допускается HTTP/1.1 fallback. Для обязательного минимального TLS задайте SSLVERSION отдельно: выбор HTTP/2 сам не задаёт все TLS-политики. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.33.0 |
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. |
CURL_HTTP_VERSION_3ONLYТип самой константы: int | Требовать HTTP/3 без отката к HTTP/2/1.1; отсутствие поддержки должно привести к отказу. В проверенной сборке главы HTTP3 feature выключен. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.4.0 и libcurl 7.88.0. |
CURL_HTTP_VERSION_NONEТип самой константы: int | Дать libcurl выбрать HTTP-версию. Default начиная с libcurl 8.13.0; раньше с 7.62.0 default был 2TLS, ещё раньше 1_1. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_REDIR_POST_301Тип самой константы: int | Бит: после HTTP 301 сохранить POST вместо стандартного перехода к GET. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.18.2 |
CURL_REDIR_POST_302Тип самой константы: int | Бит: после HTTP 302 сохранить POST вместо перехода к GET. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.18.2 |
CURL_REDIR_POST_303Тип самой константы: int | Бит: после HTTP 303 сохранить POST вместо перехода к GET; это сознательное отклонение от обычного сценария «после POST открыть GET». Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.25.1 |
CURL_REDIR_POST_ALLТип самой константы: int | Объединение битов сохранения POST для 301, 302, 303. Это не разрешение redirect вообще: FOLLOWLOCATION включается отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.18.2 |
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 + Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_TIMECOND_NONEТип самой константы: int | 0, default: временное условие выключено. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
Время ожидания и медленная передача
Покупатель не должен ждать интеграцию бесконечно. Общий TIMEOUT включает установление соединения; CONNECTTIMEOUT ограничивает только эту фазу. LOW_SPEED_LIMIT и LOW_SPEED_TIME отвечают на другой вопрос: достаточно ли долго скорость оставалась ниже заданной. Выбирайте бюджет из задачи приложения, а не из произвольного большого числа.
- Соединение занимает часть общих 1500 ms
- CONNECTTIMEOUT_MS=500 ограничивает эту часть
- TIMEOUT_MS=1500 не прибавляет ещё 1500 после соединения
- При отказе приложение решает, безопасен ли повтор
| Константа | Назначение, договор и границы |
|---|---|
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. |
CURLOPT_TIMEOUT_MSТип самой константы: int | То же общее время, что TIMEOUT, в миллисекундах. При системном resolver DNS может иметь секундное разрешение и минимальный таймаут порядка секунды. Это не обещание прерывания ровно в указанную миллисекунду; CONNECTTIMEOUT_MS отдельно ограничивает фазу соединения. Значение/результат: int: миллисекунды. По умолчанию: 0: общего лимита нет. Версии: Доступно с libcurl 7.16.2. Native API: libcurl 7.16.2. |
DNS, IP, локальные соединения и TCP
До HTTP-ответа клиент выбирает адрес, открывает соединение и иногда повторно использует уже открытое. DNS cache, IPRESOLVE, RESOLVE и CONNECT_TO решают разные задачи. Замена фактического IP не обязана менять Host/TLS имя. TCP keepalive проверяет простаивающее соединение средствами ОС, а не отправляет повторный HTTP-запрос.
- URL задаёт имя сервиса
- DNS/RESOLVE выбирает IP
- Proxy/socket/интерфейс определяет маршрут
- Пул может предоставить уже открытое соединение
- Только затем выполняется прикладной обмен
| Константа | Назначение, договор и границы |
|---|---|
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLOPT_FORBID_REUSEТип самой константы: int | После передачи закрыть соединение и не помещать его в пул. Это отличается от FRESH_CONNECT, который требует новое соединение до передачи. Без причины ухудшает повторные запросы из-за DNS/TCP/TLS затрат. Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7. |
CURLOPT_FRESH_CONNECTТип самой константы: int | Начать следующую передачу на новом соединении, даже если есть пригодное в пуле. Не обязывает закрыть новое соединение после ответа; для этого есть FORBID_REUSE. Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7. |
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. |
CURLOPT_IPRESOLVEТип самой константы: int | Выбор семейства IP при DNS/подборе соединения из пула: V4,V6 либо любое. Если URL уже содержит числовой IP, настройка не запрещает его семейство. Это не фильтр допустимых сетей и не защита от внутренних адресов. Значение/результат: int CURL_IPRESOLVE_*. По умолчанию: WHATEVER. Версии: Доступно с libcurl 7.10.8. Native API: libcurl 7.10.8. |
CURLOPT_LOCALPORTТип самой константы: int | Локальный port исходящего socket; не port удалённого сервера. Полезен вместе с LOCALPORTRANGE и INTERFACE в контролируемой сети. Один закреплённый занятый port может сорвать запрос. Значение/результат: int,0 либо1..65535. По умолчанию: 0: выбирает ОС. Версии: Доступно с libcurl 7.15.2. Native API: libcurl 7.15.2. |
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. |
CURLOPT_MAXCONNECTSТип самой константы: int | Максимум сохранённых соединений easy cache после использования; при заполнении закрывается старейшее. Не ограничивает суммарное число активных запросов. Внутри multi эта easy-настройка игнорируется: нужен Значение/результат: int. По умолчанию: 5. Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7. |
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. |
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. |
CURLOPT_PIPEWAITТип самой константы: int | При включённом multi multiplexing ждать выяснения возможностей создающегося соединения, чтобы переиспользовать его, вместо немедленного открытия нового. Уменьшает число соединений ценой ожидания. Сам не включает Значение/результат: bool. По умолчанию: false. Версии: Доступно с PHP 7.0.7 и libcurl 7.43.0. Native API: libcurl 7.43.0. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLOPT_TCP_NODELAYТип самой константы: int | Выключить алгоритм Nagle, чтобы не задерживать малые TCP-записи ради объединения. Применяется при создании соединения; уже открытое соединение повторно не перенастраивается. Может уменьшить задержку, увеличив число малых пакетов. Значение по умолчанию стало true с libcurl 7.50. Значение/результат: bool. По умолчанию: true в текущем libcurl. Версии: Доступно с libcurl 7.11.2. Native API: libcurl 7.11.2. |
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. |
CURL_IPRESOLVE_V6Тип самой константы: int | Ограничить соединение/выбор из pool адресами IPv6; при отсутствии IPv6 маршрут может отказать. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10.8. |
CURL_IPRESOLVE_WHATEVERТип самой константы: int | Допустить семейства адресов, поддерживаемые системой; применяется к новому соединению и выбору из pool. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10.8. |
HTTP-аутентификация и credentials
Метод HTTP-аутентификации, сами учётные данные и разрешение передавать их после redirect — независимые решения. Имя опции со словом SAFE не заменяет проверенный TLS. NETRC читает credentials из файла на сервере PHP, а не из компьютера посетителя.
Сначала договоритесь с сервером о способе аутентификации, затем задавайте credentials. Bitmask перечисляет допустимые способы, но не шифрует пароль. Пример показывает только выбор: секрет и адрес не нужны, потому что запрос не выполняется.
- BASIC — один бит
- DIGEST — другой бит
- | разрешает оба
- & проверяет, что BASIC входит в маску
- 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-ключ. |
CURLAUTH_ANYSAFEТип самой константы: int | То же, но исключает Basic. Название SAFE не является гарантией современной криптографической безопасности всех остальных алгоритмов; TLS и политика сервиса всё равно нужны. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLAUTH_AWS_SIGV4Тип самой константы: int | Выбрать AWS Signature Version 4; параметры provider/region/service задаёт Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.75.0. |
CURLAUTH_BASICТип самой константы: int | HTTP Basic: имя и пароль кодируются, но не шифруются самим методом. Передавайте только через проверенный TLS. Это default HTTPAUTH libcurl. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLAUTH_BEARERТип самой константы: int | HTTP Bearer, например OAuth2 access token; токен задаётся XOAUTH2_BEARER. Владение токеном даёт доступ, поэтому не печатайте его и используйте TLS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0. |
CURLAUTH_DIGESTТип самой константы: int | HTTP Digest: ответ на challenge вместо передачи самого пароля как Basic. Поддержка и вариант алгоритма зависят от сервера/сборки; это не замена TLS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLAUTH_DIGEST_IEТип самой константы: int | Исторический вариант Digest для Internet Explorer. Современная libcurl трактует бит как обычный DIGEST; отдельное IE-поведение больше не поддерживается. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.19.3. |
CURLAUTH_GSSAPIТип самой константы: int | GSS-API-аутентификация, в частности разрешённый бит SOCKS5_AUTH. Требует подходящего GSS-API backend; не смешивайте его с HTTP Basic по одному названию auth. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.54.1 |
CURLAUTH_GSSNEGOTIATEТип самой константы: int | Старое имя HTTP Negotiate; современное соответствующее имя — Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLAUTH_NEGOTIATEТип самой константы: int | HTTP Negotiate/SPNEGO; требует GSS-API либо SSPI на Windows и настроенного окружения. Сам флаг не создаёт Kerberos-билет. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.38.0. |
CURLAUTH_NONEТип самой константы: int | Нулевая маска: без аутентификации. Для SOCKS5 это разрешение только no-auth; ноль не добавляет отдельный бит к другим алгоритмам. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10.6. |
CURLAUTH_NTLMТип самой константы: int | Историческая Microsoft NTLM challenge-response схема; использует слабые криптографические механизмы. Для нового протокола выбирайте согласованный современный способ. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
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 |
CURLAUTH_ONLYТип самой константы: int | Метабит: объединяется | с одним конкретным HTTP auth-методом, чтобы после проверки без аутентификации принимать только этот алгоритм. Сам по себе не является алгоритмом и не означает ANY. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.3. |
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, не комбинируется с другими видами входа; бит Значение/результат: string|null. По умолчанию: null. Версии: Доступно с PHP 8.2.0 и libcurl 7.75.0. Native API: libcurl 7.75.0. |
CURLOPT_DISALLOW_USERNAME_IN_URLТип самой константы: int | Запрещает userinfo с именем пользователя в Значение/результат: 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. |
CURLOPT_KEYPASSWDТип самой константы: int | Пароль приватного ключа SSLKEY либо SSH_PRIVATE_KEYFILE; это не пароль удалённой учётной записи. Для публичного сертификата пароль обычно не нужен, для зашифрованного private key — нужен. null сбрасывает; не включать значение в журналы. Значение/результат: string|null. По умолчанию: null. Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0. |
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. |
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. |
CURLOPT_NETRC_FILEТип самой константы: int | Файл credentials вместо домашнего .netrc; работает с выбранным NETRC mode, сам по себе не включает чтение. Последний путь заменяет прежний. Секреты не должны попадать в web-root, общий архив примеров или репозиторий. Значение/результат: string|null: полный путь. По умолчанию: null. Версии: Доступно с libcurl 7.11.0. Native API: libcurl 7.11.0. |
CURLOPT_PASSWORDТип самой константы: int | Пароль remote-аутентификации вместе с USERNAME. Не URL-decode автоматически как часть USERPWD; отдельный параметр удобен для двоеточий. null сбрасывает. Не равен passphrase приватного ключа KEYPASSWD. Значение/результат: string|null. По умолчанию: не задан. Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1. |
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. |
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. |
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. |
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. |
CURLOPT_USERPWDТип самой константы: int | Имя и пароль, разделённые первым двоеточием; строка не URL-декодируется. Если двоеточие необходимо в имени, задайте USERNAME/PASSWORD отдельно. HTTPAUTH выбирает способ, LOGIN_OPTIONS уточняет отдельные почтовые протоколы. Не вставляйте секреты в URL или исходники примера; TLS и политика redirect обязательны независимо от удобного формата строки. Значение/результат: string|null: user:password. По умолчанию: null. Версии: Native API: libcurl 7.1. |
CURLOPT_XOAUTH2_BEARERТип самой константы: int | OAuth2 access token. Для HTTP выбирают HTTPAUTH= Значение/результат: 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-ключ. |
CURL_NETRC_OPTIONALТип самой константы: int | Использовать .netrc при необходимости, отдавая приоритет данным из URL; явно заданные USERPWD/USERNAME имеют свой более высокий приоритет. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_NETRC_REQUIREDТип самой константы: int | Требовать .netrc и игнорировать credentials из URL; файл выбирается NETRC_FILE/окружением/домашним каталогом. За права доступа к секретному файлу отвечает приложение/владелец. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
TLS: доверие, имя, сертификаты и версии
Сертификат сервера и клиентский сертификат имеют разные роли. CAINFO/CAPATH задают, кому доверять; SSLCERT/SSLKEY подтверждают клиента при mTLS. Backend OpenSSL, Schannel, GnuTLS, Rustls и другие поддерживают разные параметры и форматы. Не переносите опцию между ними только по наличию PHP-константы.
Проверенный TLS решает две задачи: подтверждает доверие цепочке сертификата и соответствие имени адресату. Они включаются раздельно. Исправление неизвестного CA — настройка доверенного хранилища, а не отключение проверки. Версия TLS задаёт допустимый диапазон, а не гарантированно выбранный протокол.
- VERIFYPEER=true → доверенная цепочка
- VERIFYHOST=2 → нужное имя сервера
- TLSv1_2 | MAX_TLSv1_3 → диапазон 1.2…1.3
- Реальное согласование произойдёт при curl_exec
Этот вариант. | объединяет нижнюю и верхнюю границы именно по договору SSLVERSION. Вызов не проверял сертификат и не доказывает, что сервер поддерживает диапазон: передачи нет. Пример предполагает современную сборку TLS. В обычном приложении актуальный безопасный default backend часто удобнее жёсткой верхней границы.
<?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. Значение/результат: string|null: путь к файлу. По умолчанию: сборка/система; PHP curl.cainfo может переопределить. Версии: Доступно с libcurl 7.4.2. Native API: libcurl 7.4.2. |
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. |
CURLOPT_CAPATHТип самой константы: int | Каталог CA для VERIFYPEER. OpenSSL ожидает подготовленные hash-ссылки/имена через c_rehash; просто собрать произвольные файлы в папку недостаточно. Native-документация отмечает ограничение OpenSSL CAPATH на Windows: проверять backend, для воспроизводимого Windows-примера проще CAINFO-файл. Значение/результат: string|null: каталог. По умолчанию: определён при сборке. Версии: Доступно с libcurl 7.9.8. Native API: libcurl 7.9.8. |
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 | Включает сбор сведений о цепочке сертификатов для последующего Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1. |
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. |
CURLOPT_ISSUERCERTТип самой константы: int | Дополнительная проверка, что серверный сертификат выдан указанным issuer. Полезно для нужной ветви PKI. Сам переданный issuer не становится доверенным автоматически; требуется VERIFYPEER. Без неё неуспех этой проверки не считается отказом. Несовпадение может дать SSL_ISSUER_ERROR. Значение/результат: string|null: PEM-файл. По умолчанию: null. Версии: Доступно с libcurl 7.19.0. Native API: libcurl 7.19.0. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLOPT_SSLKEY_BLOBТип самой константы: int | Приватный ключ из памяти вместо SSLKEY файла; поддержка OpenSSL/Rustls,формат SSLKEYTYPE. Строка секретна, её длина и тип не подтверждают пригодности ключа. Значение/результат: string:байты приватного ключа. По умолчанию: не задан. Версии: Доступно с PHP 8.1.0 и libcurl 7.71.0. Native API: libcurl 7.71.0. |
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. |
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. |
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. |
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. |
CURLSSLOPT_ALLOW_BEASTТип самой константы: int | Разрешить старое SSL/TLS-поведение, снижающее защиту от BEAST ради совместимости. Не включать как универсальное исправление TLS; действие зависит от backend. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.25.0 |
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 |
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 |
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-ключ. |
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 |
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-ключ. |
CURL_SSLVERSION_SSLv3Тип самой константы: int | Исторический SSLv3. Современная libcurl отказывает; не обходите это отключением проверки сертификата. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_SSLVERSION_TLSv1Тип самой константы: int | Разрешить TLS1.0 и новее; название не означает «строго TLS1.0». Слишком слабый минимум для нового сервиса. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_SSLVERSION_TLSv1_0Тип самой константы: int | Минимальная версия TLS1.0; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_SSLVERSION_TLSv1_1Тип самой константы: int | Минимальная версия TLS1.1; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_SSLVERSION_TLSv1_2Тип самой константы: int | Минимальная версия TLS1.2; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_SSLVERSION_TLSv1_3Тип самой константы: int | Минимальная версия TLS1.3; более новые версии разрешены. Чтобы ограничить и максимум, объединяют | с нужным CURL_SSLVERSION_MAX_*. Backend может иметь более строгую политику. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0 |
CURL_TLSAUTH_SRPТип самой константы: int | Значение метода TLS-SRP (Secure Remote Password), если он поддерживается TLS backend. Требует TLSAUTH_USERNAME/PASSWORD; наличие константы не гарантирует backend/серверную поддержку. Это native enum; Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.21.4. |
Прокси, SOCKS и отдельный TLS к прокси
Прокси — дополнительный участник пути. При HTTPS proxy могут быть две TLS-проверки: клиента с proxy и клиента с конечным сервером внутри туннеля. PROXY_SSL_* не заменяют SSL_* конечного адресата. В SOCKS4/5 разновидности различаются, в частности, местом DNS-разрешения имени.
- PROXY задаёт посредника
- PROXY_SSL_* проверяют сертификат посредника
- CONNECT создаёт туннель к целевому host
- SSL_* проверяют уже целевой сервис
- 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. |
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. |
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. |
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. |
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. |
CURLOPT_PROXYPASSWORDТип самой константы: int | Пароль входа на proxy вместе с PROXYUSERNAME. Не пароль origin и не passphrase proxy client TLS key. Отдельный параметр не требует конструировать URL с секретом. Значение/результат: string|null. По умолчанию: не задан. Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1. |
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. |
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. |
CURLOPT_PROXYUSERNAMEТип самой константы: int | Имя пользователя proxy-протокола. Пароль задаётся PROXYPASSWORD, допустимые методы — PROXYAUTH или SOCKS-настройки. Не переносится как username origin. Значение/результат: string|null. По умолчанию: не задан. Версии: Доступно с libcurl 7.19.1. Native API: libcurl 7.19.1. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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-ответа сохраняются. Значение/результат: 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. |
CURLPROXY_HTTPSТип самой константы: int | HTTP-прокси, к которому само соединение защищено TLS. Проверки PROXY_SSL_* относятся к нему, SSL_* — к целевому серверу. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0 |
CURLPROXY_HTTP_1_0Тип самой константы: int | HTTP-прокси с HTTP/1.0 в CONNECT-запросе к туннелю. Это не принудительный HTTP/1.0 конечного сервера. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.19.3 |
CURLPROXY_SOCKS4Тип самой константы: int | SOCKS4: имя конечного сервера разрешает локальная сторона; формат ограничен возможностями SOCKS4. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10. |
CURLPROXY_SOCKS4AТип самой константы: int | SOCKS4a передаёт hostname на разрешение прокси, в отличие от обычного SOCKS4. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
CURLPROXY_SOCKS5Тип самой константы: int | SOCKS5 с локальным разрешением hostname; аутентификация настраивается отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10. |
CURLPROXY_SOCKS5_HOSTNAMEТип самой константы: int | SOCKS5 с разрешением hostname на стороне proxy. Это влияет на DNS-маршрут и политику доступа, не делает адрес автоматически безопасным. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
Cookie engine и cookie-файлы
Сохранение cookie — состояние клиента между передачами. COOKIEFILE читает исходные данные; COOKIEJAR задаёт сохранение. Ошибка записи jar может не стать ошибкой последнего HTTP-запроса, поэтому проверяйте права/жизненный цикл отдельно. Файл cookie — чувствительный файл, его нельзя размещать в публичном каталоге.
Cookie jar нужен клиенту, который сохраняет состояние между запросами одного сервиса. Это отдельное хранилище cURL, а не автоматически $_COOKIE посетителя вашего сайта. Сначала добавим искусственную несекретную cookie только в память и прочтём состояние без запроса.
- COOKIELIST получает Netscape-строку cart=42
- Cookie engine сохраняет domain/path/flags
- CURLINFO_COOKIELIST возвращает список
- Команда ALL очищает его
Этот вариант. Поля разделены табуляцией: domain, include-subdomains, path, secure, expires, name, value. Ноль означает session cookie. Пример не отправлял cookie и не создавал jar-файл. В настоящем клиенте не печатайте session tokens; не разделяйте одно 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. |
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. |
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. |
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. |
CURLOPT_COOKIESESSIONТип самой константы: int | Отмечает новую cookie-сессию: при последующей загрузке игнорировать старые cookies без даты истечения. Не удаляет автоматически всё уже находящееся в памяти и не завершает серверную авторизацию. Для очистки текущих session cookies есть COOKIELIST="SESS". Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.9.7. Native API: libcurl 7.9.7. |
Alt-Svc и HSTS
Alt-Svc разрешает использовать объявленную сервером альтернативную точку обслуживания, HSTS запоминает требование HTTPS. Они меняют будущие соединения, поэтому сведения принимаются только из доверенного контекста; отключение TLS-проверок может отравить такие кэши. READONLYFILE запрещает обратную запись, а не чтение.
- Проверенный HTTPS сообщает HSTS/Alt-Svc
- Клиент сохраняет разрешённые сведения в памяти/файле
- Следующая передача применяет политику
- Доверенный каталог и проверка TLS сохраняют границы доверия
| Константа | Назначение, договор и границы |
|---|---|
CURLALTSVC_H1Тип самой константы: int | Бит разрешения альтернативного сервиса HTTP/1.1 из Alt-Svc. Alt-Svc принимается/используется с проверенным HTTPS, не из произвольного незашифрованного объявления. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1. |
CURLALTSVC_H2Тип самой константы: int | Бит альтернативного HTTP/2. Игнорируется, если сборка не поддерживает HTTP/2. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1. |
CURLALTSVC_H3Тип самой константы: int | Бит альтернативного HTTP/3. Игнорируется без поддержки HTTP/3; этот флаг не добавляет QUIC в сборку. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1. |
CURLALTSVC_READONLYFILEТип самой константы: int | Не записывать изменённый Alt-Svc cache обратно в файл Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.64.1. |
CURLHSTS_ENABLEТип самой константы: int | Включить in-memory HSTS cache handle: известные HSTS hosts переводятся с HTTP на HTTPS. Не обещает предварительный список всех защищённых сайтов. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0 |
CURLHSTS_READONLYFILEТип самой константы: int | Не сохранять изменённый HSTS cache в файл при освобождении handle; сам cache при этом может применяться в памяти. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0 |
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. |
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. |
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. |
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. |
Callback-функции, прогресс и пауза
Обработчик передают как callable, затем libcurl вызывает его в нужной фазе. Подписи и значения возврата у обработчиков различаются: длина принятой части, строка исходящих байтов, код продолжения/отказа. Пауза означает сохранение состояния передачи, а не sleep внутри callback; для возобновления передают полную маску состояния.
Ответ может прийти несколькими частями. Callback — функция, которую вызывает libcurl по мере поступления данных. У WRITEFUNCTION первый параметр — клиент, второй — очередная строка байтов. Возврат числа подтверждает, сколько байтов принято. Чтобы сначала понять механику без сети, читаем маленький приложенный файл через file://.
- Файл содержит A42,7 и перевод строки
- WRITEFUNCTION получает очередной chunk
- Добавляет его к $received
- Возвращает strlen(chunk)
- После 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. |
CURLOPT_PREREQFUNCTIONТип самой константы: int | После установки/выбора соединения и TLS, перед данными вызывается callback(handle, remoteIp, localIp, remotePort, localPort). Вернуть Значение/результат: 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, Значение/результат: callable|null. По умолчанию: внутреннее чтение READDATA. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
CURLOPT_SSH_HOSTKEYFUNCTIONТип самой константы: int | PHP 8 callback(CurlHandle $h,int $keyType,string $key,int $keyLength):int проверяет байты hostkey, тип native CURLKHTYPE_*. Вернуть строго Значение/результат: 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; меньший результат останавливает передачу с Значение/результат: callable(CurlHandle, string): int. По умолчанию: обычный вывод PHP / RETURNTRANSFER / FILE. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
CURLOPT_WRITEHEADERТип самой константы: int | Поток для заголовков; это PHP-имя native HEADERDATA. Не путь-строка. Сохраняйте поток открытым до завершения; для управляемого разбора строк ответа применяйте HEADERFUNCTION. Несколько HTTP-ответов (100, redirect, proxy CONNECT) дают несколько блоков заголовков. Значение/результат: resource: открытый поток для записи. По умолчанию: заголовки не сохраняются в отдельный поток. Версии: Доступно с libcurl 7.1.0. Native API CURLOPT_HEADERDATA: libcurl 7.10. |
CURLOPT_XFERINFOFUNCTIONТип самой константы: int | Современный progress callback: handle, download total/current, upload total/current. Неизвестные totals равны 0; включается при NOPROGRESS=false. Возврат 0 продолжает, ненулевой — прерывает с Значение/результат: 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. |
CURLPAUSE_CONTТип самой константы: int | 0: снять паузу обоих направлений. curl_pause принимает новое полное состояние, а не отдельную команду-переключатель. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
CURLPAUSE_RECVТип самой константы: int | Маска приостанавливает получение. Если отправку тоже нужно оставить приостановленной, включите SEND через |. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
CURLPAUSE_RECV_CONTТип самой константы: int | Историческое именованное значение 0. Хотя имя говорит о получении, передача его одного в curl_pause снимает обе паузы; для состояния «отправка на паузе, чтение активно» передайте SEND. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
CURLPAUSE_SENDТип самой константы: int | Маска приостанавливает отправку. Чтобы одновременно оставить паузу чтения, включите RECV через |. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
CURLPAUSE_SEND_CONTТип самой константы: int | Историческое именованное значение 0. Передача его одного снимает обе паузы; для состояния «чтение на паузе, отправка активна» передайте RECV. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
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 |
CURL_PREREQFUNC_ABORTТип самой константы: int | Ответ prereq callback: отменить передачу с Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.4.0 и libcurl 7.80.0. |
CURL_PREREQFUNC_OKТип самой константы: int | Ответ prereq callback: продолжить после установления/выбора соединения и handshake, но до отправки запроса. Не означает, что соединения до этого момента не было. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.4.0 и libcurl 7.80.0. |
CURL_READFUNC_PAUSEТип самой константы: int | Особый ответ read callback: сейчас нет данных, приостановить чтение из источника. Пустая строка означала бы EOF; возобновление организует приложение через curl_pause. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
CURL_WRITEFUNC_PAUSEТип самой константы: int | Особый ответ write callback: временно приостановить получение. При возобновлении libcurl может заново доставить удержанный chunk; не записывать его дважды. Обычно callback возвращает strlen($chunk), то есть число принятых байтов. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.18.0. |
Получение, отправка и файловые потоки
Путь-строка, открытый stream resource и callback не взаимозаменяемы. INFILE предоставляет источник, FILE — приёмник, INFILESIZE описывает исходящий размер. Буфер — рабочая порция памяти; он не ограничивает весь ответ. MAXFILESIZE и прикладной лимит получателя решают задачу суммарного объёма.
Для больших ответов удобнее сразу писать в поток. Ресурс fopen — открытый канал записи, а не имя файла. Следующий опыт использует php://temp, чтобы не перезаписывать пользовательские файлы; отдельный приложенный stock.csv служит источником.
- stock.csv → file:// URL
- FILE получает открытый $destination
- curl_exec пишет байты
- rewind возвращает позицию в начало
- 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, максимум Значение/результат: int, байты. По умолчанию: 16384 (CURL_MAX_WRITE_SIZE). Версии: Доступно с libcurl 7.10. Native API: libcurl 7.10. |
CURLOPT_CRLFТип самой константы: int | Исторически заменяет Unix LF на CRLF при передаче. Меняет байты, поэтому не годится для двоичных payload, подписей или файлов, где нужна точная сохранность. Не является общей перекодировкой текста. Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
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. |
CURLOPT_FILETIMEТип самой константы: int | Попросить дату изменения удалённого ресурса. Сервер/протокол может не предоставить её; Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.5.0. Native API: libcurl 7.5. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLOPT_SAFE_UPLOADТип самой константы: int | Отключает старую магию @filename в POSTFIELDS: строка, начинающаяся@, остаётся полем. Файлы отправляются CURLFile/CURLStringFile. Попытка false в PHP 8.5 выбрасывает ValueError; вернуть старый небезопасный режим нельзя. Это не проверка содержимого/размера самого файла. Значение/результат: true. По умолчанию: всегда true в текущем PHP. |
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. |
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 имеют реальные побочные эффекты; повторять их вслепую нельзя.
- Клиент соединяется с управляющим FTP endpoint
- USE_SSL=ALL требует TLS для команд и данных
- Сервер сообщает адрес/порт канала данных
- Клиент открывает канал и передаёт файл
- Приложение отдельно решает замену, append и безопасный повтор
| Константа | Назначение, договор и границы |
|---|---|
CURLFTPAUTH_DEFAULTТип самой константы: int | Оставить libcurl выбор порядка AUTH SSL / AUTH TLS для FTPS. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLFTPAUTH_SSLТип самой константы: int | Сначала AUTH SSL, после отказа AUTH TLS. Это названия FTP-команд, не разрешение использовать небезопасный SSLv3. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLFTPAUTH_TLSТип самой константы: int | Сначала AUTH TLS, после отказа AUTH SSL; имеет смысл при включённом USE_SSL. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLFTPMETHOD_DEFAULTТип самой константы: int | Стандартный способ обхода FTP-пути (MULTICWD). Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.15.3. |
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. |
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-ключ. |
CURLFTPSSL_CCC_ACTIVEТип самой константы: int | Инициировать завершение TLS на управляющем канале и дождаться ответа. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.16.2. |
CURLFTPSSL_CCC_NONEТип самой константы: int | Не выполнять Clear Command Channel: сохранить защищённый управляющий канал. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.16.2. |
CURLFTPSSL_CCC_PASSIVEТип самой константы: int | Дождаться инициативы сервера завершить TLS, не инициировать и не отвечать тем же шагом. CCC сознательно делает управление незашифрованным. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.16.1. |
CURLFTPSSL_CONTROLТип самой константы: int | Требовать TLS управляющего соединения, иначе отказ. Канал данных FTP этим требованием не защищён автоматически. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLFTPSSL_NONEТип самой константы: int | Не пытаться включить TLS для соответствующего протокола. Старое имя Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLFTPSSL_TRYТип самой константы: int | Попытаться TLS, но продолжить без него при невозможности. Сервер может закрыть соединение после неуспешного согласования; для обязательной защиты TRY не подходит. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
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. |
CURLOPT_DIRLISTONLYТип самой константы: int | FTP/SFTP: список имён без размеров/дат; FTP использует NLST, поэтому некоторые серверы не включают каталоги/ссылки. Сам флаг подразумевает listing даже без конечного /. POP3: список сообщений/размера сообщения вместо получения тела. FILE-каталоги уже перечисляются так. Конфликтует с WILDCARDMATCH и лишает его эффекта. Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLOPT_POSTQUOTEТип самой константы: int | FTP/SFTP-команды после успешной передачи; при ошибке передачи не исполняются. Синтаксис/возможные изменения файлов описывает QUOTE. Последний список заменяет прежний. Это реальные операции на сервере, не безвредный текстовый post-hook. Значение/результат: array<string>. По умолчанию: пустой список. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
CURLOPT_PREQUOTEТип самой константы: int | FTP-команды после выбора transfer type, до файлового обмена; не для directory listing. В отличие от QUOTE/POSTQUOTE не применяется к SFTP. Последний список заменяет прежний; внешние значения не превращать в команды. Значение/результат: array<string>. По умолчанию: пустой список. Версии: Доступно с libcurl 7.9.5. Native API: libcurl 7.9.5. |
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. |
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. |
CURLOPT_USE_SSLТип самой константы: int | STARTTLS/переход на TLS для FTP, SMTP, POP3, IMAP и подходящих протоколов. TRY допускает продолжение без TLS; CONTROL защищает только управляющий FTP-канал, для других протоколов эквивалентен ALL. ALL требует TLS; отказ может иметь native код CURLE_USE_SSL_FAILED (в PHP для него есть историческое имя Значение/результат: int: CURLUSESSL_*. По умолчанию: CURLUSESSL_NONE. Версии: Доступно с libcurl 7.17.0. Native API: libcurl 7.17.0. |
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. |
CURLUSESSL_ALLТип самой константы: int | Требовать TLS и для управления, и для данных, иначе отказ. Для чтения ошибки libcurl использует USE_SSL_FAILED; не путать с простым наличием HTTPS в URL. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.17.0. |
CURLUSESSL_CONTROLТип самой константы: int | Требовать TLS управляющего соединения, иначе отказ. Канал данных FTP этим требованием не защищён автоматически. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.17.0. |
CURLUSESSL_NONEТип самой константы: int | Не пытаться включить TLS для соответствующего протокола. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.17.0. |
CURLUSESSL_TRYТип самой константы: int | Попытаться TLS, но продолжить без него при невозможности. Сервер может закрыть соединение после неуспешного согласования; для обязательной защиты TRY не подходит. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.17.0. |
SFTP/SCP: ключ сервера и вход клиента
Здесь два вопроса: тот ли это сервер и имеет ли клиент право войти. KNOWNHOSTS/fingerprint/HOSTKEYFUNCTION проверяют сервер, PRIVATE_KEYFILE/PUBLIC_KEYFILE/AUTH_TYPES — клиента. Проверка нового соединения не означает повторную проверку каждого запроса при reuse. Не превращайте ошибку host key в callback, всегда возвращающий OK.
- Заранее доверенный host key записан в known_hosts
- При новом соединении сравнивается ключ сервера
- Затем клиент подтверждает свой вход ключом/разрешённым методом
- Только после этого передаётся файл
| Константа | Назначение, договор и границы |
|---|---|
CURLKHMATCH_LASTТип самой константы: int | Служебная граница перечисления; не настоящий исход проверки host key и не разрешённая политика доверия. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.3.0 и libcurl 7.19.6 |
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 |
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 |
CURLSSH_AUTH_ANYТип самой константы: int | Разрешить любой поддерживаемый SSH-метод; сервер/сборка выбирают конкретный. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLSSH_AUTH_DEFAULTТип самой константы: int | Стандартный выбор допустимых SSH-методов, соответствует ANY. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLSSH_AUTH_GSSAPIТип самой константы: int | Разрешить SSH GSS-API, если сборка backend имеет такую возможность. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.58.0 |
CURLSSH_AUTH_HOSTТип самой константы: int | Исторически host-based SSH-аутентификация; текущая libcurl отмечает, что этот бит не имеет эффекта. Это не проверка host key сервера. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLSSH_AUTH_KEYBOARDТип самой константы: int | Интерактивный keyboard authentication; поведение/поддержка зависят от SSH backend. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLSSH_AUTH_NONEТип самой константы: int | Нулевая маска без SSH-аутентификации. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURLSSH_AUTH_PASSWORDТип самой константы: int | Разрешить SSH-аутентификацию паролем. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
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 требует продуманного учёта результата и повторов.
- MAIL_FROM задаёт отправителя доставки
- MAIL_RCPT перечисляет адресатов доставки
- Сервер принимает или отвергает каждого адресата
- Только затем передаётся подготовленное сообщение
| Константа | Назначение, договор и границы |
|---|---|
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. |
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. |
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. |
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.
- DESCRIBE → описание потока
- SETUP → транспорт и Session ID
- PLAY с Session ID → начать
- 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. |
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. |
CURL_RTSPREQ_DESCRIBEТип самой константы: int | Получить описание медиапотока. В Accept указывают понимаемые форматы; без собственного заголовка libcurl добавляет application/sdp. Для DESCRIBE применяются условные time headers из TIMECONDITION. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
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. |
CURL_RTSPREQ_PAUSEТип самой константы: int | Поставить воспроизведение на паузу. Один момент RANGE, например npt=25, задаёт время остановки. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURL_RTSPREQ_PLAYТип самой константы: int | Начать воспроизведение. RANGE может задать интервал, например npt=10-15. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURL_RTSPREQ_RECEIVEТип самой константы: int | Принимать interleaved RTP data. Это особый режим получения данных, а не отправка команды PLAY. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURL_RTSPREQ_RECORDТип самой константы: int | Попросить сервер записывать сессию; RANGE уточняет временной интервал записи. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
CURL_RTSPREQ_SETUPТип самой константы: int | Настроить транспорт сессии; детали передаются отдельно через RTSP_TRANSPORT. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.20.0. |
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. |
TELNET, TFTP и WebSocket
Эти протоколы решают отдельные задачи: TELNET согласует терминал, TFTP передаёт файлы по простому протоколу, WebSocket обменивается кадрами после установления соединения. Наличие CURLWS_RAW_MODE не создаёт недостающие PHP-методы native WebSocket API. Сначала проверяйте protocols и требуемую модель обмена.
- Устройство/сервис задаёт реальный протокол
- curl_version показывает возможности сборки
- Опции настраивают только этот протокол
- Кадры, блоки или терминальные параметры имеют собственные правила
| Константа | Назначение, договор и границы |
|---|---|
CURLOPT_TELNETOPTIONSТип самой константы: int | Список строк option=value для TELNET: TTYPE — тип терминала, XDISPLOC — display, NEW_ENV — переменная окружения. Повторная установка заменяет прежний список. Это протокольные параметры, не команды оболочки; TELNET не обеспечивает конфиденциальность как SSH. Значение/результат: array<string>. По умолчанию: пустой список. Версии: Доступно с libcurl 7.7.0. Native API: libcurl 7.7. |
CURLOPT_TFTP_BLKSIZEТип самой константы: int | Запрашиваемый размер блока TFTP. Сервер должен согласовать расширение; при отказе используется базовый размер 512. Большой блок не гарантирует ускорение в сети с потерями. TFTP_NO_OPTIONS отключает согласование и делает этот выбор недействующим. Значение/результат: int: 8…65464 байта. По умолчанию: 512. Версии: Доступно с libcurl 7.19.4. Native API: libcurl 7.19.4. |
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 бит Значение/результат: int: маска CURLWS_*. По умолчанию: 0. Версии: Доступно с PHP 8.3.0 и libcurl 7.86.0. Native API: libcurl 7.86.0. |
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 |
Multi: параллельность, соединения и результаты
Multi управляет несколькими easy handles. Лимит одновременных соединений, размер сохраняемого пула и число HTTP/2/3 потоков — разные пределы. CURLM_* сообщает о работе multi API; результат отдельной передачи всё ещё CURLE_*. CURLMSG_DONE обозначает сообщение о завершении, которое надо прочитать, а не успех любого ответа.
- Добавить независимые easy handles
- Применить лимиты соединений/потоков
- Продвигать multi и ожидать события
- Прочитать CURLMSG_DONE каждого handle
- Проверить его 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. |
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 — Значение/результат: ключ curl_multi_setopt; значение callable для PUSHFUNCTION, int для остальных ключей этой группы. Версии: Доступно с libcurl 7.16.0. Native API: libcurl 7.16.0. |
CURLMOPT_PUSHFUNCTIONТип самой константы: int | callable(CurlHandle $parent, CurlHandle $pushed, array $headers): int в PHP 8+: parent — исходный запрос, pushed — новый push handle, headers — заголовки push promise. Вернуть Значение/результат: ключ 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. |
CURLMSG_DONEТип самой константы: int | Тип сообщения «передача завершилась». Сообщение содержит easy handle и отдельный result CURLE_*; DONE сам по себе не доказывает успех ответа. Значение/результат: int: тип сообщения из curl_multi_info_read. |
CURLM_ADDED_ALREADYТип самой константы: int | Попытка второй раз добавить уже добавленный easy handle. Не считать это успешной регистрацией нового запроса. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.32.1. |
CURLM_BAD_EASY_HANDLEТип самой константы: int | Некорректный easy handle для multi-операции. На границе PHP объект неправильного класса обычно отсекается TypeError ещё до libcurl. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.9.6. |
CURLM_BAD_HANDLEТип самой константы: int | Некорректный multi handle в libcurl. PHP дополнительно проверяет тип объекта на входе функции. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.9.6. |
CURLM_CALL_MULTI_PERFORMТип самой константы: int | Исторический запрос немедленно повторить обработку multi. Начиная с libcurl 7.20.0 этот статус не используется; не строить современный цикл вокруг ожидания этого значения. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.9.6. |
CURLM_INTERNAL_ERRORТип самой константы: int | Внутренняя ошибка механизма multi; это не HTTP-код отдельного ответа. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.9.6. |
CURLM_OKТип самой константы: int | Multi-операция выполнена без ошибки на уровне multi. Отдельные запросы всё ещё могут завершиться с CURLE_*; читать result через curl_multi_info_read. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.9.6. |
CURLM_OUT_OF_MEMORYТип самой константы: int | Не хватило памяти для обработки multi. Не повторять бесконечно ту же нагрузку. Значение/результат: int: результат multi API, не HTTP-статус и не CURLE результат отдельной передачи. Версии: Доступно с libcurl 7.9.6. |
CURLPIPE_HTTP1Тип самой константы: int | Исторический бит HTTP/1.1 pipelining: несколько запросов по соединению до получения ответов. С libcurl 7.62.0 pipelining удалён и бит не действует; это не HTTP/2 multiplexing. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.43.0. |
CURLPIPE_MULTIPLEXТип самой константы: int | Разрешить одновременные HTTP/2 или HTTP/3 streams в соединении при поддержке протокола. Это разрешение, а не обещание объединения любых запросов. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.43.0. |
CURLPIPE_NOTHINGТип самой константы: int | Нулевая маска: не запрашивать multiplexing. Последовательное повторное использование соединения этим не запрещается. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.43.0. |
CURL_PUSH_DENYТип самой константы: int | Ответ callback: отвергнуть предложенный сервером push. Без callback libcurl отвергает push по умолчанию. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.1.0 и libcurl 7.44.0 |
CURL_PUSH_OKТип самой константы: int | Ответ callback: принять предложенный HTTP/2 push handle. Не означает, что передача уже завершена успешно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.1.0 и libcurl 7.44.0 |
Share: какие данные можно разделить
Share объединяет выбранные кэши, а не запускает конкурентные запросы. Один multi уже разделяет некоторые данные своих handles. Не передавайте cookie-состояние разных пользователей в общее хранилище. Обычный CurlShareHandle и persistent share PHP 8.5 имеют отдельные границы; отдельная константа lock-data не обещает потокобезопасности во всех native сценариях.
- Создать share
- CURLSHOPT_SHARE получает CURL_LOCK_DATA_DNS
- CURLOPT_SHARE присоединяет нужные easy handles
- Cookie и TLS session остаются отдельными, если их не включили
- Менять 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. |
CURLSHOPT_NONEТип самой константы: int | Нулевой служебный элемент перечисления share-настроек. Не является командой «отключить всё»: используйте UNSHARE с конкретным видом данных. Значение/результат: ключ curl_share_setopt; значение одного CURL_LOCK_DATA_* (кроме служебного NONE). Версии: Доступно с libcurl 7.10.3. Native API CURLSHOPT_SHARE: libcurl 7.10.3. |
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. |
CURLSHOPT_UNSHAREТип самой константы: int | Ключ curl_share_setopt: значением передать один CURL_LOCK_DATA_* для прекращения разделения этого вида данных. Вызывать между передачами, когда share не используется. Это не Значение/результат: ключ curl_share_setopt; значение одного CURL_LOCK_DATA_* (кроме служебного NONE). Версии: Доступно с libcurl 7.10.3. Native API: libcurl 7.10.3. |
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. |
CURL_LOCK_DATA_COOKIEТип самой константы: int | Общие cookies easy handles. Cookie engine включается отдельно, например COOKIEFILE=""; настройка share сама его не включает. Общие cookies между одновременно работающими native threads не поддерживаются. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10.3. |
CURL_LOCK_DATA_DNSТип самой константы: int | Общий кеш результатов DNS. Handles одного multi и так используют общий DNS cache; отдельный share нужен при другой организации handles. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10.3. |
CURL_LOCK_DATA_PSLТип самой константы: int | Общая Public Suffix List — список публичных суффиксов для корректных cookie boundaries. Это избегает независимых обновлений кеша; внутри одного multi PSL уже разделяется. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0. |
CURL_LOCK_DATA_SSL_SESSIONТип самой константы: int | Общий кеш TLS sessions для сокращения повторного handshake. Один handle и handles одного multi уже могут повторно использовать sessions. Это не отключение проверки сертификатов. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.10.3. |
Локальные прикладные метки
PRIVATE помогает сопоставить завершившийся handle с заказом/заданием. Это локальный контекст приложения, не опция аутентификации и не место, которое удалённый сервер сможет прочитать.
При нескольких запросах полезно помнить, к какой задаче относится handle. PRIVATE хранит прикладную метку локально; она не превращается в HTTP-заголовок и не отправляется серверу.
- Массив order=42, attempt=1
- CURLOPT_PRIVATE сохраняет значение
- CURLINFO_PRIVATE возвращает его приложению
- Сеть не участвует
Этот вариант. 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: ключ заказа, массив контекста или объект. Получается через Значение/результат: mixed. По умолчанию: не задан; getinfo тогдаfalse. Версии: Доступно с libcurl 7.10.3. Native API: libcurl 7.10.3. |
Результат, размеры и тайминги CURLINFO
getinfo читает сведения последней передачи. Часть полей остаётся от предыдущего запроса при reuse; читайте сразу после нужного exec и сохраняйте рядом с заданием. Не принимайте отсутствие информации за успешную проверку. native C-типы отличаются от PHP int/float/string/array и их диапазонов.
Отказ передачи и код HTTP-ответа — разные уровни. file:// вообще не имеет HTTP-статуса, поэтому успешное чтение файла не должно выдавать 200. На нём удобно увидеть разницу между CURLINFO_* и CURLE_* без сети.
- curl_exec возвращает содержимое файла
- curl_errno = CURLE_OK: передача успешна
- CURLINFO_RESPONSE_CODE = 0: HTTP-ответа не было
- Длина тела: байты фактически полученной строки
Этот вариант. CURLE_OK равен 0. Для HTTP API дополнительно проверяйте ожидаемый диапазон статусов и формат body. curl_exec не возвращает false только из-за HTTP 404, если политика FAILONERROR не включена. Отсутствующее Content-Length не означает пустой ответ.
<?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, а не гарантированно фактическое значение после пользовательского Значение/результат: string|false. Версии: Доступно с PHP 8.3.0 и libcurl 7.84.0 Native API: libcurl 7.84.0. |
CURLINFO_CAPATHТип самой константы: int | Встроенный default путь к каталогу CA, а не обязательно пользовательская настройка CAPATH. Может отсутствовать или относиться к неактивному TLS backend. Значение/результат: string|false. Версии: Доступно с PHP 8.3.0 и libcurl 7.84.0 Native API: libcurl 7.84.0. |
CURLINFO_CERTINFOТип самой константы: int | Информация о цепочке сертификатов сервера, если до передачи включён Значение/результат: array|false. Версии: Native API: libcurl 7.19.1. |
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. |
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. |
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. |
CURLINFO_COOKIELISTТип самой константы: int | Все известные libcurl cookies, включая просроченные; без cookies — пустой массив. Cookies, импортированные строкой Set-Cookie без domain, здесь не экспортируются. Содержимое конфиденциально. Значение/результат: array|false. Версии: Native API: libcurl 7.14.1. |
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 — неизвестно. До запроса требуется Значение/результат: int|false. Версии: Native API: libcurl 7.5. |
CURLINFO_FILETIME_TТип самой константы: int | Тот же Unix timestamp или -1, через native curl_off_t вместо long; нужна предварительная Значение/результат: int|false. Версии: Доступно с PHP 7.3.0 и libcurl 7.59.0 Native API: libcurl 7.59.0. |
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. |
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. |
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-передачи: Значение/результат: int|false. Версии: Доступно с PHP 7.3.0 и libcurl 7.50.0 Native API: libcurl 7.50.0. |
CURLINFO_LASTONEТип самой константы: int | Последний служебный элемент native enum CURLINFO. Не информационное поле и не обещание непрерывного диапазона допустимых PHP getinfo ключей. Значение/результат: int: служебная граница. |
CURLINFO_LOCAL_IPТип самой константы: int | IP локального конца последнего соединения; строка может содержать IPv6. Это не публичный IP приложения за NAT. Значение/результат: string|false. Версии: Native API: libcurl 7.21.0. |
CURLINFO_LOCAL_PORTТип самой константы: int | Локальный порт последнего TCP/UDP соединения; QUIC использует UDP. В актуальном libcurl -1, если соединения/портов не было. Значение/результат: int|false. Версии: Native API: libcurl 7.21.0. |
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. |
CURLINFO_OS_ERRNOТип самой константы: int | Системный errno сетевого сбоя: значения зависят от ОС. С libcurl 8.8.0 сохранённый errno очищается перед передачей; в старых версиях мог остаться от предыдущего запроса того же handle. Не трактовать положительный errno без контекста ошибки. Значение/результат: int|false. Версии: Native API: libcurl 7.12.2. |
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. |
CURLINFO_PRIMARY_PORTТип самой константы: int | Порт фактического удалённого TCP/UDP соединения; при proxy — порт proxy. В актуальном libcurl -1 при отсутствии соединения или протокола с портами. Значение/результат: int|false. Версии: Native API: libcurl 7.21.0. |
CURLINFO_PRIVATEТип самой константы: int | В PHP возвращает сохранённое значение Значение/результат: mixed. Версии: Native API: libcurl 7.10.3. |
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. |
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-отказа после Значение/результат: int|false. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 Native API: libcurl 7.73.0. |
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. |
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. |
CURLINFO_REFERERТип самой константы: int | Referer, использованный в последнем запросе. При AUTOREFERER может отличаться от первоначальной настройки; данные URL могут быть конфиденциальны. Значение/результат: string|false. Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0 Native API: libcurl 7.76.0. |
CURLINFO_REQUEST_SIZEТип самой константы: int | Общий размер выданных HTTP-запросов в байтах; при FOLLOWLOCATION может относиться к нескольким запросам, а не только одному. Значение/результат: int|false. Версии: Native API: libcurl 7.4.1. |
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. |
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. |
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. |
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. |
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. |
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. |
CURLINFO_TOTAL_TIME_TТип самой константы: int | Полное время предыдущей передачи, включая DNS, соединение и обмен. Единица — микросекунды. При автоматических переходах соответствующие интервалы запросов суммируются; это не отдельная длительность только последнего handshake. Значения могут быть 0 при повторном использовании соединения/отсутствии этапа. Значение/результат: int|false. Версии: Доступно с PHP 7.3.0 и libcurl 7.61.0 Native API: libcurl 7.61.0. |
CURLINFO_USED_PROXYТип самой константы: int | 1 если предыдущая передача использовала proxy, 0 иначе. Это проверка фактического пути, а не только наличия Значение/результат: int|false. Версии: Доступно с PHP 8.5.0 и libcurl 8.7.0. Native API: libcurl 8.7.0. |
Диагностика: текст, заголовки и данные
VERBOSE/DEBUGFUNCTION нужны для диагностики протокола. CURLINFO_TEXT и другие значения в debug callback — типы сообщений, а не все допустимые ключи curl_getinfo. Сам тип сообщения не делает его безопасным для логирования: используйте разрешённые метрики и исключайте секреты. Не пишите полный debug output в публичные журналы.
- Приложение знает ID задания
- После передачи получает код ошибки, статус и время
- В журнал идут эти разрешённые поля
- 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. |
CURLINFO_DATA_OUTТип самой константы: int | Исходящие данные протокола; могут содержать отправляемый body и секреты. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные. Значение/результат: int: тип события DEBUGFUNCTION. Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6. |
CURLINFO_HEADER_INТип самой константы: int | Входящие заголовки или данные, похожие на заголовки выбранного протокола. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные. Значение/результат: int: тип события DEBUGFUNCTION. Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6. |
CURLINFO_HEADER_OUTТип самой константы: int | В DEBUGFUNCTION это тип исходящих заголовков. В PHP также специальный ключ curl_setopt($handle, Значение/результат: две роли: 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. |
CURLINFO_SSL_DATA_OUTТип самой константы: int | Исходящие бинарные TLS-данные. Не использовать как текстовый журнал прикладного запроса. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные. Значение/результат: int: тип события DEBUGFUNCTION. Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6. |
CURLINFO_TEXTТип самой константы: int | Информационный текст диагностики. Это значение аргумента $type debug callback, а не самостоятельное поле curl_getinfo. Журнал может раскрывать credentials и персональные данные. Значение/результат: int: тип события DEBUGFUNCTION. Версии: Native API CURLOPT_DEBUGFUNCTION: libcurl 7.9.6. |
CURLOPT_DEBUGFUNCTIONТип самой константы: int | При VERBOSE=true получать сообщения семи CURLINFO_* debug типов: TEXT, HEADER_IN/OUT, DATA_IN/OUT, SSL_DATA_IN/OUT. Данные могут быть бинарными/сжатыми; тип TEXT тоже может содержать секрет. PHP callback не обязан возвращать native код 0: его договор void. Значение/результат: callable(CurlHandle, int, string): void. По умолчанию: стандартный диагностический обработчик. Версии: Доступно с PHP 8.4.0. Native API: libcurl 7.9.6. |
CURLOPT_STDERRТип самой константы: int | Куда libcurl пишет диагностический текст, прежде всего при VERBOSE. PHP ожидает пригодный stream resource и преобразует его для native API; это не путь-строка. Поток должен оставаться открытым во время передачи. Журнал может содержать Authorization, Cookie и персональные данные; не выводите его посетителю. Значение/результат: resource: открытый поток для записи. По умолчанию: stderr. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
CURLOPT_VERBOSEТип самой константы: int | Расширенная диагностика передачи в STDERR либо DEBUGFUNCTION. Может раскрывать заголовки, token, cookie и данные; даже тип Значение/результат: bool. По умолчанию: false. Версии: Доступно с libcurl 7.1.0. Native API: libcurl 7.1. |
CURLE и CURLPX: смысл отказа
CURLE_* — транспорт/протокол/локальный callback. HTTP 404/500 — другой уровень. CURLPX_* уточняют отказ proxy, который читают через CURLINFO_PROXY_ERROR. Один код не говорит, безопасен ли повтор: отправленный POST мог уже выполнить действие, даже если ответ потерян. Для идемпотентности нужен прикладной договор.
- curl_exec вернул false
- curl_errno определяет класс CURLE ошибки
- Для proxy дополнительно CURLINFO_PROXY_ERROR
- Собственная причина callback объясняет локальную остановку
- Повтор разрешается только политикой конкретной операции
| Константа | Назначение, договор и границы |
|---|---|
CURLE_ABORTED_BY_CALLBACKТип самой константы: int | Callback сам потребовал остановку передачи. Различать сознательную политику отмены, лимит данных и ошибку обработчика. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_BAD_CALLING_ORDERТип самой константы: int | Сохранённое историческое имя: старый «неправильный порядок вызовов». Сейчас alias CURLE_OBSOLETE44; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_BAD_CONTENT_ENCODINGТип самой константы: int | Получено неизвестное или непригодное для декодирования content/transfer encoding. Проверять заголовки ответа и поддержку декодера. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_BAD_DOWNLOAD_RESUMEТип самой константы: int | Невозможно продолжить скачивание с заданного смещения: оно выходит за границы файла. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_BAD_FUNCTION_ARGUMENTТип самой константы: int | Неподходящее значение аргумента native-функции. PHP может раньше выбросить TypeError/ValueError; не ожидать этот код для любой ошибки PHP-вызова. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_BAD_PASSWORD_ENTEREDТип самой константы: int | Сохранённое историческое имя: старый «неправильный пароль». Сейчас alias CURLE_OBSOLETE46; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_COULDNT_CONNECTТип самой константы: int | Не удалось установить соединение с конечным узлом или proxy. Это ещё не HTTP-ответ сервера. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_COULDNT_RESOLVE_HOSTТип самой константы: int | DNS не смог разрешить имя целевого узла. Опечатка имени и недоступность DNS — разные возможные причины. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_COULDNT_RESOLVE_PROXYТип самой константы: int | Не удалось разрешить имя proxy; это не обязательно проблема DNS самого целевого сайта. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FAILED_INITТип самой константы: int | Сбой начальной инициализации: внутренняя ошибка либо невозможность выделить базовые ресурсы. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FILESIZE_EXCEEDEDТип самой константы: int | Превышен установленный предел размера файла/передачи. Проверять собственную политику MAXFILESIZE, а не автоматически повышать её. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FILE_COULDNT_READ_FILEТип самой константы: int | Для file:// не удалось открыть локальный файл: например, путь неверен или недостаточны права. Это локальная файловая ошибка, не HTTP 404. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_ACCESS_DENIEDТип самой константы: int | Исторический alias CURLE_REMOTE_ACCESS_DENIED в актуальном заголовке libcurl. Удалённый ресурс недоступен; для FTP это, например, запрет смены каталога. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_BAD_DOWNLOAD_RESUMEТип самой константы: int | Исторический alias Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_CANT_GET_HOSTТип самой константы: int | Внутренний сбой определения узла для нового FTP-соединения. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_CANT_RECONNECTТип самой константы: int | Опасное историческое имя: его числовой слот переиспользован; актуальный заголовок через OBSOLETE alias приводит к CURLE_HTTP2. Сегодня это ошибка HTTP/2 framing, а не буквальный смысл старого имени. При диагностике использовать curl_error/curl_strerror и версию libcurl. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_COULDNT_GET_SIZEТип самой константы: int | Сохранённое историческое имя: старый отказ FTP SIZE. Сейчас alias CURLE_OBSOLETE32; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_COULDNT_RETR_FILEТип самой константы: int | FTP RETR получил неожиданный ответ либо завершился нулевой передачей в ситуации, которую libcurl признал ошибочной. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_COULDNT_SET_ASCIIТип самой константы: int | Сохранённое историческое имя: старый отказ ASCII-режима. Сейчас alias CURLE_OBSOLETE29; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_COULDNT_SET_BINARYТип самой константы: int | Исторический alias CURLE_FTP_COULDNT_SET_TYPE в актуальном заголовке libcurl. Не удалось выбрать FTP-режим передачи binary или ASCII. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_COULDNT_STOR_FILEТип самой константы: int | Исторический alias CURLE_UPLOAD_FAILED в актуальном заголовке libcurl. Не началась загрузка; FTP-сервер мог отклонить STOR. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_COULDNT_USE_RESTТип самой константы: int | FTP-сервер отклонил REST — команду возобновления с заданного смещения. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_PARTIAL_FILEТип самой константы: int | Исторический alias Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_PORT_FAILEDТип самой константы: int | FTP PORT не принят; часто требуется корректный адрес активного соединения в FTPPORT и разрешённый сетевой маршрут. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_QUOTE_ERRORТип самой константы: int | Исторический alias CURLE_QUOTE_ERROR в актуальном заголовке libcurl. Одна из дополнительных команд QUOTE не выполнена; для FTP ответ >=400. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_SSL_FAILEDТип самой константы: int | Исторический alias CURLE_USE_SSL_FAILED в актуальном заголовке libcurl. Не удалось обеспечить запрошенный уровень защищённого FTP. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
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-ключ. |
CURLE_FTP_WEIRD_PASS_REPLYТип самой константы: int | После передачи FTP-пароля сервер прислал неожиданный код ответа. Не выводить сам пароль при диагностике. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_WEIRD_PASV_REPLYТип самой константы: int | Ответ на FTP PASV/EPSV не удалось использовать для пассивного соединения. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_WEIRD_SERVER_REPLYТип самой константы: int | Исторический alias Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_WEIRD_USER_REPLYТип самой константы: int | Опасное историческое имя: его числовой слот переиспользован; актуальный заголовок через OBSOLETE alias приводит к CURLE_FTP_ACCEPT_TIMEOUT. Сегодня это таймаут ожидания соединения active FTP, а не буквальный смысл старого имени. При диагностике использовать curl_error/curl_strerror и версию libcurl. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FTP_WRITE_ERRORТип самой константы: int | Сохранённое историческое имя: старый FTP write error. Сейчас alias CURLE_OBSOLETE20; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_FUNCTION_NOT_FOUNDТип самой константы: int | Сохранённое историческое имя: исторически отсутствовала функция zlib; код не используется с 7.53.0. Сейчас alias CURLE_OBSOLETE41; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_GOT_NOTHINGТип самой константы: int | Сервер ничего не вернул в ситуации, когда протокол требовал ответ. Это не синоним корректного пустого HTTP body. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_HTTP_NOT_FOUNDТип самой константы: int | Исторический alias Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_HTTP_PORT_FAILEDТип самой константы: int | Исторический alias CURLE_INTERFACE_FAILED в актуальном заголовке libcurl. Не удалось использовать выбранный исходящий сетевой интерфейс; название не описывает современный смысл. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_HTTP_POST_ERRORТип самой константы: int | Сохранённое историческое имя: историческая внутренняя ошибка POST; код не используется с 7.56.0. Сейчас alias CURLE_OBSOLETE34; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_HTTP_RANGE_ERRORТип самой константы: int | Исторический alias CURLE_RANGE_ERROR в актуальном заголовке libcurl. Сервер не поддерживает или не принимает запрос диапазона. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_HTTP_RETURNED_ERRORТип самой константы: int | При FAILONERROR=true HTTP-статус >=400 преобразован в ошибку libcurl. У опции есть протокольные исключения вокруг аутентификации; проверять HTTP-код отдельно. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_LDAP_CANNOT_BINDТип самой константы: int | Не выполнен LDAP bind, то есть этап связывания/аутентификации LDAP-сессии. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_LDAP_INVALID_URLТип самой константы: int | Сохранённое историческое имя: старый некорректный LDAP URL. Сейчас alias CURLE_OBSOLETE62; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_LDAP_SEARCH_FAILEDТип самой константы: int | LDAP-сервер не выполнил поиск по запросу. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_LIBRARY_NOT_FOUNDТип самой константы: int | Сохранённое историческое имя: старое отсутствие библиотеки. Сейчас alias CURLE_OBSOLETE40; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_MALFORMAT_USERТип самой константы: int | Сохранённое историческое имя: старый неверный формат пользователя. Сейчас alias CURLE_OBSOLETE24; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_OBSOLETEТип самой константы: int | Сохранённое историческое имя: служебное устаревшее значение. Сейчас alias CURLE_OBSOLETE50; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_OKТип самой константы: int | 0: libcurl не сообщил транспортной ошибки. HTTP 404/500 без FAILONERROR всё ещё могут дать Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_OPERATION_TIMEDOUTТип самой константы: int | Истёк один из применимых лимитов времени. По одному коду нельзя решить, был ли это DNS, соединение, медленный поток или общий TIMEOUT. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_OPERATION_TIMEOUTEDТип самой константы: int | Исторический alias Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_OUT_OF_MEMORYТип самой константы: int | Не выделена необходимая память. Слепое повторение той же нагрузки может усугубить ситуацию. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_PARTIAL_FILEТип самой константы: int | Сервер сообщил ожидаемый размер, а фактически переданное количество оказалось другим — меньше или больше. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_PROXYТип самой константы: int | Ошибка proxy handshake. Дополнительный Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLE_READ_ERRORТип самой константы: int | Не удалось читать локальный источник либо read callback сообщил ошибку. Это направление загрузки данных на сервер. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_RECV_ERRORТип самой константы: int | Ошибка получения сетевых данных. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SEND_ERRORТип самой константы: int | Ошибка отправки сетевых данных. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SHARE_IN_USEТип самой константы: int | Сохранённое историческое имя: старое «share используется». Сейчас alias CURLE_OBSOLETE57; modern libcurl не выдаёт этот код для новых операций. Не строить новую обработку ошибки по одному этому старому имени. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSHТип самой константы: int | Неуточнённая ошибка SSH-сессии. Дополнительный curl_error помогает отличить проблемы ключей, входа и протокола. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с libcurl 7.16.1. |
CURLE_SSL_CACERTТип самой константы: int | Исторический alias CURLE_PEER_FAILED_VERIFICATION в актуальном заголовке libcurl. Не прошла проверка сертификата/SSH fingerprint. Коды унифицированы с libcurl 7.62.0; до унификации peer verification имел другой номер. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_CACERT_BADFILEТип самой константы: int | Не удалось прочитать файл доверенных CA: проверить путь, права, формат и CAINFO/CAPATH. Не лечить отключением проверки сертификатов. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_CERTPROBLEMТип самой константы: int | Проблема локального клиентского сертификата; не смешивать с проверкой сертификата удалённого сервера. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_CIPHERТип самой константы: int | Не удалось использовать заданный набор шифров TLS. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_CONNECT_ERRORТип самой константы: int | Сбой TLS handshake. Причины включают формат/права файлов, пароли, протокол и сертификаты; нужна безопасно очищенная подробность curl_error. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_ENGINE_NOTFOUNDТип самой константы: int | Запрошенный криптографический engine не найден в используемом TLS backend. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_ENGINE_SETFAILEDТип самой константы: int | Не удалось назначить выбранный SSL crypto engine по умолчанию. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_SSL_PEER_CERTIFICATEТип самой константы: int | Исторический alias CURLE_PEER_FAILED_VERIFICATION в актуальном заголовке libcurl. Не прошла проверка удалённой стороны; это не проблема локального клиентского сертификата. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
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-ключ. |
CURLE_TOO_MANY_REDIRECTSТип самой константы: int | Цепочка переходов превысила MAXREDIRS. Проверять циклы и адрес назначения; бесконечное разрешение переходов не исправляет первопричину. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_UNKNOWN_TELNET_OPTIONТип самой константы: int | Исторический alias CURLE_UNKNOWN_OPTION в актуальном заголовке libcurl. Неизвестная native-настройка; PHP дополнительно проверяет допустимость ключей. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_UNSUPPORTED_PROTOCOLТип самой константы: int | Протокол URL неизвестен или отсутствует в сборке. Проверить схему URL и curl_version()["protocols"]. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_URL_MALFORMATТип самой константы: int | URL имеет неприемлемый формат. Наличие корректного формата не является разрешением обращаться к адресу. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_URL_MALFORMAT_USERТип самой константы: int | Исторический alias CURLE_NOT_BUILT_IN в актуальном заголовке libcurl. Функция/протокол/опция не включены при сборке libcurl; старое имя вводит в заблуждение. Совпадение чисел не делает старое имя точным диагнозом. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLE_WEIRD_SERVER_REPLYТип самой константы: int | Ответ удалённого сервера нельзя разобрать по ожидаемому протоколу. С libcurl 7.51.0 это имя заменило FTP_WEIRD_SERVER_REPLY. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.51.0 |
CURLE_WRITE_ERRORТип самой константы: int | Не удалось сохранить полученные данные или write callback вернул неверное число принятых байтов/ошибку. Это направление ответа, а не отправки файла. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. |
CURLPX_BAD_ADDRESS_TYPEТип самой константы: int | Proxy указал или запрос потребовал неподдерживаемый тип адреса SOCKS. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_BAD_VERSIONТип самой константы: int | В SOCKS-ответе оказалась неожиданная версия протокола. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_CLOSEDТип самой константы: int | Proxy-соединение закрыто во время согласования. Конкретная стадия может уточняться текстом ошибки. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_GSSAPIТип самой константы: int | Не удалось выполнить GSS-API согласование SOCKS. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_GSSAPI_PERMSGТип самой константы: int | Ошибка GSS-API защиты/разбора отдельного сообщения согласования SOCKS. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
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 |
CURLPX_IDENTD_DIFFERТип самой константы: int | SOCKS4-сервер сообщил несовпадение user ID с identd (ответ 93). Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_LONG_HOSTNAMEТип самой константы: int | Имя целевого узла слишком длинное для соответствующего поля SOCKS; длина поля считается в байтах. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_LONG_PASSWDТип самой константы: int | Пароль не помещается в поле SOCKS5 user/password; предел протокола — 255 байтов, а не символов Unicode. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_LONG_USERТип самой константы: int | Имя пользователя слишком длинное для доступного поля/буфера SOCKS; у SOCKS5 user/password предел поля — 255 байтов. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_NO_AUTHТип самой константы: int | Не найден разрешённый и поддерживаемый способ SOCKS-аутентификации; сервер может вернуть «нет приемлемого метода». Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_OKТип самой константы: int | 0: подробный proxy-код отсутствует или равен успеху. В частности, если ответа proxy нет, значение тоже 0; это не отдельное доказательство успешного соединения. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_RECV_ADDRESSТип самой константы: int | Не удалось получить адресную часть proxy-ответа. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_RECV_AUTHТип самой константы: int | Ошибка чтения ответа proxy-аутентификации. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_RECV_CONNECTТип самой константы: int | Не удалось получить ожидаемый ответ при установлении SOCKS-соединения. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_RECV_REQACKТип самой константы: int | Не удалось получить подтверждение запроса SOCKS. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
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 |
CURLPX_REQUEST_FAILEDТип самой константы: int | Proxy отказал в запросе; для SOCKS4 это ответ 91. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_RESOLVE_HOSTТип самой константы: int | Не разрешено имя целевого узла на стадии подготовки SOCKS; место DNS зависит от типа SOCKS proxy. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_SEND_AUTHТип самой константы: int | Не удалось отправить данные proxy-аутентификации. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_SEND_CONNECTТип самой константы: int | Не удалось отправить данные согласования proxy-соединения. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_SEND_REQUESTТип самой константы: int | Не удалось отправить SOCKS-запрос. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_UNKNOWN_FAILТип самой константы: int | Неизвестный отказ proxy, не сопоставленный более точному виду. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_UNKNOWN_MODEТип самой константы: int | Proxy выбрал неизвестный или не поддерживаемый приложением способ аутентификации. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
CURLPX_USER_REJECTEDТип самой константы: int | SOCKS5 user/password-аутентификация отвергнута сервером. Значение/результат: int: код результата, не HTTP-статус и не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.73.0 |
Возможности установленной libcurl
CURL_VERSION_* — биты возможностей в curl_version()[features], а не номера версии PHP. Некоторые исторические биты сохранены для совместимости и больше ничего не включают. CURLVERSION_NOW — отдельное понятие версии структуры native API. Нужные библиотеки/протоколы могут отсутствовать даже в новой libcurl.
Наличие константы и поддержка функции в установленной библиотеке — разные проверки. curl_version сообщает сборку: версия, список протоколов, битовая маска features, TLS backend. Эти значения меняются между компьютерами; следующий пример выводит проверяемую структуру, не выдумывает одинаковую строку версии для всех.
- curl_version → массив
- version → строка версии
- protocols → список схем
- 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. |
CURL_VERSION_ALTSVCТип самой константы: int | Бит поддержки разбора HTTP Alt-Svc и связанных настроек альтернативных сервисов. Сам по себе не включает хранение/использование Alt-Svc в handle. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.6 и libcurl 7.64.1 |
CURL_VERSION_ASYNCHDNSТип самой константы: int | Бит асинхронного DNS resolver: уменьшает блокировки multi и позволяет более точно соблюдать таймауты, в том числе Windows. Не означает, что любой PHP-код стал асинхронным. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.10.7 |
CURL_VERSION_BROTLIТип самой константы: int | Сборка умеет распаковывать HTTP Content-Encoding br через Brotli; запрос/декодирование включают отдельно через ACCEPT_ENCODING. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.57.0 |
CURL_VERSION_CONVТип самой константы: int | Историческая поддержка перекодирования через callbacks. С libcurl 7.82.0 бит всегда 0, механизм устарел. Это не способ проверить поддержку UTF-8 в приложении. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.15.4 |
CURL_VERSION_CURLDEBUGТип самой константы: int | Исторический бит отладки памяти libcurl; с 8.19.0 совпадает с DEBUG и устарел. Не является включённым Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.6 и libcurl 7.19.6 |
CURL_VERSION_DEBUGТип самой константы: int | libcurl собран с возможностями отладки; это свойство сборки, а не включение вывода сетевых секретов. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.10.6 |
CURL_VERSION_GSASLТип самой константы: int | Сборка использует GNU SASL и поддерживает дополнительные SCRAM-SHA способы аутентификации. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.76.0 |
CURL_VERSION_GSSAPIТип самой константы: int | libcurl связан с GSS-API для Kerberos/SPNEGO; в соответствующем окружении возможны credentials текущего пользователя. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.38.0 |
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) |
CURL_VERSION_HSTSТип самой константы: int | Сборка поддерживает HSTS. Проверка бита не включает HSTS cache; HSTS_CTRL/HSTS настраиваются отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.74.0 |
CURL_VERSION_HTTP2Тип самой константы: int | В сборке есть HTTP/2. Сервер, TLS/ALPN и политика handle ещё должны позволить фактический HTTP/2. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.33.0 |
CURL_VERSION_HTTP3Тип самой константы: int | В сборке есть HTTP/3 и QUIC. Присутствие самой PHP-константы не означает установленного бита; учебная Windows-сборка может иметь константу без HTTP/3. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.66.0 |
CURL_VERSION_HTTPS_PROXYТип самой константы: int | Есть поддержка TLS-соединения к HTTPS proxy. Это отдельный TLS-слой от HTTPS конечного сервера. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.52.0 |
CURL_VERSION_IDNТип самой константы: int | Есть поддержка интернационализированных доменов IDNA. Это не Unicode-нормализация произвольных частей URL. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.12.0 |
CURL_VERSION_IPV6Тип самой константы: int | Сборка умеет IPv6; доступность маршрута и AAAA у конкретного узла проверяются отдельно. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_VERSION_KERBEROS4Тип самой константы: int | Исторический Kerberos V4 для FTP; legacy-бит устарел с libcurl 7.33.0. Не выбирать его для современной настройки входа. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_VERSION_KERBEROS5Тип самой константы: int | Поддерживается Kerberos V5 для соответствующих протоколов/аутентификации, например FTP, IMAP, LDAP, POP3, SMTP и SOCKS5. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0 |
CURL_VERSION_LARGEFILEТип самой константы: int | Сборка поддерживает большие файлы, включая размеры >2 GiB. Точность PHP int/float и возможности файловой системы остаются отдельными ограничениями. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с libcurl 7.33.0 |
CURL_VERSION_LIBZТип самой константы: int | Есть zlib для HTTP deflate/gzip возможностей. Наличие библиотеки не включает автоматическую распаковку без соответствующей настройки. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_VERSION_MULTI_SSLТип самой константы: int | Сборка включает несколько TLS backends. Это не означает одновременную проверку соединения всеми backend; curl_version сообщает активный и доступные. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.56.0 |
CURL_VERSION_NTLMТип самой константы: int | Есть поддержка HTTP NTLM; фактическая аутентификация зависит от разрешённых HTTPAUTH/PROXYAUTH и сервера. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.10.6 |
CURL_VERSION_NTLM_WBТип самой константы: int | Историческое делегирование NTLM winbind helper; функция удалена из libcurl 8.8.0. Наличие константы не восстанавливает удалённый механизм. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.22.0 |
CURL_VERSION_PSLТип самой константы: int | Есть Public Suffix List для отказа от cookies на публичный суффикс. Это часть cookie domain policy, не общий фильтр URL. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.6 и libcurl 7.47.0 |
CURL_VERSION_SPNEGOТип самой константы: int | Есть механизм SPNEGO для согласования аутентификации. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.10.8 |
CURL_VERSION_SSLТип самой константы: int | Есть TLS/SSL возможности, например HTTPS/FTPS. Конкретные версии протокола и шифры определяет TLS backend. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. |
CURL_VERSION_SSPIТип самой константы: int | Windows-сборка использует SSPI для поддерживаемых Kerberos/NTLM/SPNEGO/Digest механизмов и, при настройке, credentials текущего пользователя. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.13.2 |
CURL_VERSION_TLSAUTH_SRPТип самой константы: int | TLS backend поддерживает SRP-аутентификацию. Эта специализированная возможность не равна обычной проверке X.509 сертификата. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.3.0 и libcurl 7.21.4 |
CURL_VERSION_UNICODEТип самой константы: int | Поддержка Windows Unicode в именах файлов и передаваемых native-опциях. HTTP body остаётся байтами и автоматически в UTF-8 не преобразуется. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.72.0 |
CURL_VERSION_UNIX_SOCKETSТип самой константы: int | Поддерживаются Unix domain sockets. Это локальный транспорт до сервиса; формат HTTP поверх него остаётся отдельным протоколом. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 7.0.7 и libcurl 7.40.0 |
CURL_VERSION_ZSTDТип самой константы: int | Поддерживается HTTP Content-Encoding zstd через библиотеку Zstandard. Значение/результат: int: значение или битовая маска, не CURLOPT-ключ. Версии: Доступно с PHP 8.2.0 и libcurl 7.72.0 |
Старые имена, неработающие и удалённые настройки
Старый код нужно уметь прочитать, поэтому устаревшие имена сохранены с точными ограничениями. Alias может работать, неработающая опция может успешно приниматься, удалённая может вообще не существовать. Проверка defined защищает только обращение к имени; она не превращает старое поведение в современное.
- Определить имя и его старое назначение
- Проверить alias/deprecated/removed статус
- Выбрать действующую замену по договору
- Не подавлять предупреждение вместо исправления причины
| Константа | Назначение, договор и границы |
|---|---|
CURLOPT_BINARYTRANSFERТип самой константы: int | С PHP5.5 ничего не делает, с PHP8.4 константа deprecated. Двоичные строки RETURNTRANSFER сохраняет без этой опции. Для сохранения изображения не требуется «включать бинарность». Значение/результат: исторический bool. По умолчанию: не действует. Версии: Не используется с PHP 5.5.0. Устарело с PHP 8.4.0. |
CURLOPT_DNS_USE_GLOBAL_CACHEТип самой константы: int | Старый глобальный DNS cache был нетредобезопасен; native не использует его с7.62, PHP8.4 также явно сообщает отсутствие эффекта. Для совместного кеша использовать share с Значение/результат: исторический 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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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_RTSP_SESSION_ERROR | Native имя несоответствия RTSP Session ID. Native код 86 может прийти числом в curl_errno, хотя PHP не экспортирует имя. Для сообщения используйте curl_strerror/curl_error и сохраняйте контекст RTSP; не подменяйте код другой похожей ошибкой. |
CURLGSSAPI_DELEGATION_NONE | Native нулевое значение: не делегировать GSSAPI credentials. Для PHP-опции GSSAPI_DELEGATION это 0; отдельное имя PHP не экспортирует. |
CURLOPT_MAIL_RCPT_ALLOWFAILS | Современное правильное native написание. PHP сохраняет историческое MAIL_RCPT_ALLLOWFAILS с тремя L; не исправляйте его на отсутствующий PHP-идентификатор. |
CURL_HET_DEFAULT | Native рекомендуемая задержка Happy Eyeballs; для описанного текущего договора 200 ms. В PHP задайте число/собственную политику через HAPPY_EYEBALLS_TIMEOUT_MS, а не необъявленное имя. |
CURL_MAX_WRITE_SIZE | Native предел типичной порции данных write callback (обычно 16 KiB), не гарантированный размер каждого chunk и не лимит всего ответа. PHP не экспортирует это имя; callback принимает фактическую длину строки. |
CURL_UPKEEP_INTERVAL_DEFAULT | Native default интервала upkeep 60000 ms. PHP не экспортирует имя; обслуживание всё равно требует явного curl_upkeep. |
Практика после справочника: выберите три настройки своего клиента и запишите для каждой тип, единицы/default, ожидаемый эффект и границу проверки. Затем добавьте обработку отказа конфигурации до curl_exec. Не переносите в приложение все найденные флаги: каждый должен отвечать конкретному требованию.
Полный указатель cURL по действиям
Все функции и методы этой категории связаны с подробными карточками. Настройки и константы расположены выше по семействам; старые методы и изменения версий помечены в соответствующих местах.
| Действие | Функции и методы |
|---|---|
| Создать и настроить запрос | curl_init; curl_setopt; curl_setopt_array; curl_copy_handle; curl_reset; curl_close |
| Выполнить, приостановить и получить результат | curl_exec; curl_pause; curl_upkeep; curl_getinfo; curl_errno; curl_error; curl_strerror; curl_version |
| Кодирование URL | curl_escape; curl_unescape |
| Файловые части multipart | curl_file_create; CURLFile::__construct; CURLFile::getFilename; CURLFile::getMimeType; CURLFile::getPostFilename; CURLFile::setMimeType; CURLFile::setPostFilename; CURLStringFile::__construct |
| Несколько независимых передач | curl_multi_init; curl_multi_add_handle; curl_multi_exec; curl_multi_select; curl_multi_info_read; curl_multi_getcontent; curl_multi_remove_handle; curl_multi_close; curl_multi_errno; curl_multi_strerror; curl_multi_setopt; curl_multi_get_handles |
| Разделяемые кеши | curl_share_init; curl_share_setopt; curl_share_errno; curl_share_strerror; curl_share_close; curl_share_init_persistent |
Функции и методы этой темы
Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.
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 устарел. Современный код прекращает хранить ненужные ссылки. Текст ответа остаётся обычной строкой.
В архиве есть 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 и массивы объясняют эти понятия отдельно.
| Часть вызова | Договор и границы |
|---|---|
| handle | CurlHandle с PHP8; прежде resource. |
| Версии | До PHP8 закрывала ресурс; с8.0 NOP, с8.5 deprecated. Старый пример PHP.net про удаление handle относится к прошлому поведению. |
| Возврат | Нет возвращаемого результата. В современном PHP жизнью объекта управляют ссылки; unset удаляет конкретную ссылку, не все ссылки во всём приложении. |
- $first держит CurlHandle
- $second = $first — тот же объект
- unset($first) удаляет первую ссылку
- $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.
<?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 при настройке второго.
- Первый клиент: id1 и таймауты
- Копия: те же опции, затем URL id2
- Два последовательных запроса
- Молоток 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. |
- Настроить первый handle
- curl_copy_handle → новый объект
- Изменить URL второго
- Первый 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 не обещаются очищенными.
- Клиент настроен на POST
- reset убирает настройки, но сохраняет объект
- Заново URL id2, RETURNTRANSFER и лимиты
- GET возвращает Перчатки 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';
$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. Возвращаемого значения нет. |
- Клиент был настроен на POST
- curl_reset
- Нужно заново задать URL и получение тела
- Cookies/кэш требуют отдельной политики
Этот вариант. Без новой настройки адреса следующий curl_exec не знает, куда обращаться.
<?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 не подходит как единственная очистка перед обслуживанием другого пользователя. Безопаснее разделять соответствующие состояния по владельцам.
<?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: у них другие словари.
- Порт 99999 недопустим → запрос не отправлен
- exec=false, errno=CURLE_URL_MALFORMAT
- Фактическая диагностика записана в transport-error.json
- Исправленный локальный 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. |
- message[result] содержит CURLE_*
- curl_strerror выбирает описание
- Журнал получает код и общий смысл
- Решение о повторе учитывает саму операцию
Этот вариант. Это текст текущего 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 отменяет это кодирование. Амперсанд внутри имени не должен превратиться в разделитель двух параметров.
- Исходное имя: Молоток & Кисть
- escape → одна закодированная строка параметра
- GET /inspect?name=…
- $_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 и массивы объясняют эти понятия отдельно.
| Часть вызова | Договор и границы |
|---|---|
| handle | CurlHandle; сетевой запрос для кодирования не выполняется. |
| string | Байты одного компонента, например поисковой фразы. Сначала выбирают кодировку текста. |
| Возврат | Процентно закодированная строка либо false. Кодировать весь готовый URL нельзя: двоеточие и разделители тоже станут данными. |
- Фраза tea & cake
- Пробел → %20, & → %26
- Собрать ?q= с этим значением
- Сервер получает одну поисковую фразу
Этот вариант. %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. Экранирование не проверяет разрешённость адреса назначения.
<?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 отменяет это кодирование. Амперсанд внутри имени не должен превратиться в разделитель двух параметров.
- Исходное имя: Молоток & Кисть
- escape → одна закодированная строка параметра
- GET /inspect?name=…
- $_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 и массивы объясняют эти понятия отдельно.
| Часть вызова | Договор и границы |
|---|---|
| handle | CurlHandle; запрос не выполняется. |
| string | Процентно закодированная строка. Плюс остаётся плюсом, в отличие от urldecode. |
| Возврат | Декодированные байты либо false. Может содержать NUL/разделители; результат не становится проверенным URL или безопасным путём. |
- tea%20%26%20cake
- Декодировать только значение
- Получить tea & cake
- Отдельно проверить допустимость данных
Этот вариант. Выбор зависит от формата: 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 и поддержка конкретного протокола — разные требования.
- Получить protocols и version установленной библиотеки
- Проверить HTTP до создания запроса
- Сохранить окружение в curl-environment.json
- Выполнить обычный запрос каталога
В архиве есть 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/протокола в библиотеке не доказывает корректность сертификатов, доступность сети или поддержку функции сервером. |
- curl_version сообщает фактическую сборку
- Проверяем HTTPS/HTTP2/нужные константы
- Подбираем возможности клиента
- Отдельно проверяем обмен с сервером
Этот вариант. Последнее 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-слоя. Не выключайте проверку сертификатов ради того, чтобы запрос перестал выдавать ошибку.
<?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 может получить повторно.
- Первая порция Молотка → PAUSE, пока ничего не записано
- Цикл объявляет resumed=true до CONT
- Возобновление может сразу снова вызвать callback
- Порция добавлена один раз → Молоток 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 и массивы объясняют эти понятия отдельно.
| Часть вызова | Договор и границы |
|---|---|
| handle | Handle активной передачи. Вызов для нового неактивного handle не запускает ожидание и может вернуть ошибку. |
| flags | CURLPAUSE_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:// для такой паузы не подходит. |
- Callback получил порцию READY
- Пока не может принять → PAUSE без записи
- Потребитель готов → CONT
- Та же порция приходит снова и записывается один раз
Этот вариант. На 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 и не даёт гарантии, что следующая операция будет успешной.
- Первый HTTP1.1 GET → Молоток 8
- upkeep завершает проверку кеша соединений
- Второй явный GET → Перчатки 15
- Два разных тела появились от двух 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 и массивы объясняют эти понятия отдельно.
| Часть вызова | Договор и границы |
|---|---|
| handle | CurlHandle с потенциально сохранённым соединением/кэшем. Функция сама не создаёт бизнес-запрос. |
| Версия | PHP8.2+, сборка libcurl7.62+. Проверяйте наличие на целевом сервере. |
| Возврат | true при успешном выполнении проверки либо false при отказе. true не означает, что были отправлены байты или что соединение теперь гарантированно живо. |
| Протокол | PHP.net описывает HTTP2 PING; свежий libcurl также описывает MQTT upkeep при наличии такой поддержки. Интервал задаёт CURLOPT_UPKEEP_INTERVAL_MS; одного задания интервала недостаточно — функцию нужно вызывать. |
| Кэш | Начиная с libcurl8.10 обслуживание может затрагивать соединения общего connection cache, а не только использованные этим easy handle. |
- Ранее открыто HTTP2-соединение
- Приложение выполняет другую работу
- После интервала вызывает upkeep
- Протокол может отправить 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.
<?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-части для сервера. Создание объекта само ничего не отправляет.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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. |
- На диске: storage/act-42.txt
- CURLFile: путь + text/plain + act.txt
- POSTFIELDS[document] → часть multipart
- Получатель: поле 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-части для сервера. Создание объекта само ничего не отправляет.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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 создают объект одного класса. Процедурное имя не означает другой способ передачи файла. |
- curl_file_create(path, mime, name)
- Возвращается CURLFile
- $fields[document] = объект
- 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Передать файл инвентаризации и прочитать подтверждённое содержимое. Это локальный путь чтения, а не имя, которое получит сервер. Проверка файла предшествует передаче.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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 текущего объекта. |
| Возврат | Сохранённый путь, не содержимое файла и не имя на стороне получателя. Метод не проверяет существование и права. |
- $document хранит act.txt
- getFilename → act.txt
- is_readable проверяет доступ сейчас
- Доставка проверяется отдельно по ответу
Этот вариант. В интерфейсе пользователю показывайте 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 поставит у части. Это чтение настройки, не анализ фактических байтов файла.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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. Это не результат анализа файла. |
- Создали с text/plain
- getMimeType вернул text/plain
- Байты могли быть любого вида
- При необходимости отдельно определяем MIME через fileinfo
Этот вариант. Тип сообщает получателю, как интерпретировать часть запроса; он не превращает двоичные байты в текст.
<?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; сервер не должен доверять этому имени как пути.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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. Переименование на диске не происходит. |
- Источник private/order-42.dat
- postname = act.txt
- getPostFilename → act.txt
- Читатель получает понятное имя
Этот вариант. Этот вывод рассчитан на 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 до отправки. Не преобразует содержимое и не делает невалидный файл допустимым.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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 заново. |
- CURLFile создан с пустым mime
- setMimeType(text/csv)
- getMimeType → text/csv
- Теперь передаём объект в POSTFIELDS
Этот вариант. Возвращать изменённый объект из метода не требуется: изменяется текущий экземпляр $report.
<?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-части. Файл на диске не переименовывается.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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. |
- Путь report-internal.dat
- setPostFilename(report.txt)
- POSTFIELDS[document] остаётся document
- Получатель видит 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, а не с диска. Это удобно для небольшого сформированного отчёта; весь текст уже находится в памяти.
- inventory.txt содержит Молоток;8 и перевод строки
- Ключ inventory становится именем поля multipart
- PHP-сервер читает $_FILES[inventory] и свой временный файл
- Ответ содержит имя 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. |
- $csv = строки отчёта
- new CURLStringFile($csv, orders.csv, text/csv)
- POSTFIELDS[report] → multipart
- У PHP-приёмника $_FILES[report], не обычный $_POST[report]
Этот вариант. Свойства публичные. Для чтения используются ->data, ->postname и ->mime; getter/setter-методов CURLFile у этого класса нет.
<?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-клиентам.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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 и не фоновая работа после завершения скрипта. |
- curl_multi_init создаёт пустой multi
- curl_init создаёт отдельный easyhandle
- add_handle связывает easy с multi
- 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-ответа.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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 вашей переменной сам по себе не отменяет передачу. |
- Создан easy для one.txt
- Первый add → CURLM_OK
- Второй add того же объекта → ошибка
- В 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Получить два самостоятельных ответа каталога. Отсоединяет клиент от диспетчера, в том числе после завершения. Это не удаление полученной строки и не чтение сообщения о завершении.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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. Снимайте нужное сообщение/метрики до удаления; необработанные события очереди могут исчезнуть. |
- Клиент добавлен в multi
- remove_handle убирает его
- exec пустого multi сообщает running=0
- Клиент можно использовать отдельно
В опытах 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 может повторить бизнес-действие.
<?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 возвращает управление без уничтожения объекта; срок жизни объекта определяется ссылками.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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. Удаление всех передач не откатывает уже выполненные серверные изменения. |
- Добавили one.txt
- curl_multi_close удаляет клиента из multi
- 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.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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-скрипт с таким циклом всё ещё занят до конца; тяжёлый код между шагами задерживает передачи. |
- exec пустого multi
- Возврат CURLM_OK — диспетчер исправен
- Переменная running получает 0
- Очередь завершений пуста
Этот вариант. 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 при проверке отдельной передачи.
<?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Получить два самостоятельных ответа каталога. Ожидает возможности следующего шага до указанного числа секунд. Ноль означает отсутствие готовой активности за интервал, а не окончание всех передач.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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 тоже недопустимы. В обычном цикле берут доли секунды, не этот максимум. |
- Нет прикреплённых передач
- select с timeout0 проверяет готовность
- Возвращает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
$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. Сам вызов не запускает сеть и не подтверждает транспортный успех.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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. Большие тела лучше обрабатывать потоком и ограничивать объём. |
- До RETURNTRANSFER буфер не выбран → null
- После настройки буфер есть, но пуст
- После завершения в нём будет тело
Этот вариант. Первый null описывает настройку, второй ответ — пока не наполненный буфер. Ни один не является HTTP-кодом ошибки.
<?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 обычно не транспортная ошибка.
<?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; они относятся к отдельным передачам.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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-массив хранит свою ссылку, но необработанные библиотечные события после удаления не обещаны. |
- Только создали multi
- info_read не находит сообщений
- false: сейчас нечего обрабатывать
Этот вариант. Значение12 сохранено намеренно. Ветку обработки выполняют только после $message !== 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.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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 ошибки отдельного клиента. |
- Создали multi
- multi_errno читает последнее состояние
- 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 не взаимозаменяемы.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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_code | CURLM_* код, например возврат add_handle/exec или multi_errno. CURLE_* коды отдельной передачи сюда не подставляют. |
| Возврат | Строка либо null по PHP-сигнатуре. В проверенной libcurl8.22 неизвестный код тоже даёт строку Unknown error, поэтому строка не подтверждает допустимость кода. Точная английская фраза не является договором бизнес-логики. |
- Передаём CURLM_OK
- Получаем техническую строку
- Приложение проверяет число, не английскую фразу
Этот вариант. Сравнивается наличие описания, чтобы пример не зависел от формулировки конкретной 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Получить два самостоятельных ответа каталога. Задаёт лимит соединений диспетчера до выполнения. Он не равен гарантированной скорости или числу одновременно занятых серверных работников.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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. |
- Создали multi
- Настроили максимум2 всего и1 на хост
- Будущие передачи соблюдают параметры соединений
Этот вариант. Само принятие настройки ещё не измеряет параллелизм. Большую очередь приложения всё равно нужно ограничивать по памяти и требованиям партнёра.
<?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 нельзя без проверки превращать в конфигурацию клиента.
<?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-клиенты. Их можно сопоставить с запросами, но наличие клиента в этом массиве не означает завершённую передачу.
- Созданы два easy-клиента: id1 и id2
- multi-loop.php чередует exec и ожидание, собирая сообщения
- Для каждого сообщения отдельно проверен CURLE-код, для каждого клиента HTTP200
- Тела выводятся в выбранном порядке: Молоток 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 храните свой массив клиентов. |
- Пустой multi → []
- Добавили клиента
- 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 элемента снимка.
<?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 не начинают делиться автоматически.
- Первый клиент посылает GET без Cookie
- Сервер отвечает Set-Cookie: theme=blue%20sky
- Cookie engine сохраняет значение в общем share
- Второй клиент отправляет 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 нужен, когда требуется общий кеш у отдельных клиентов. |
- share_init выдаёт share
- share_setopt выбирает DNS
- Два easyhandle могут подключиться к этому share
Этот вариант. Это только настройка. Здесь ещё не было DNS-запроса и измерения ускорения.
<?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 и тело ответа остаются его собственными.
- Первый клиент посылает GET без Cookie
- Сервер отвечает Set-Cookie: theme=blue%20sky
- Cookie engine сохраняет значение в общем share
- Второй клиент отправляет 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-объект сюда не подходит: его набор фиксируется при создании. |
| option | PHP поддерживает CURLSHOPT_SHARE и CURLSHOPT_UNSHARE. Неизвестный option даёт ValueError в PHP8.5.11. Низкоуровневые C-callback опции блокировок не являются автоматически доступными PHP-настройками. |
| value | CURL_LOCK_DATA_* категория: COOKIE, DNS, SSL_SESSION, CONNECT, PSL — доступность зависит от библиотеки/сборки. Каждую категорию задают отдельно; не OR-маска. |
| Возврат | true при успехе, false при отказе libcurl; share_errno даёт числовую причину. Изменение используемого share может вернуть ошибку IN_USE. Сначала настройте его, потом подключайте клиентов. |
- Создали share
- Включили общий DNS
- Отключили DNS до использования
- Обе операции сообщают 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 молча игнорируется, поэтому не используйте его как обещанное отсоединение.
<?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.
- Первый клиент посылает GET без Cookie
- Сервер отвечает Set-Cookie: theme=blue%20sky
- Cookie engine сохраняет значение в общем share
- Второй клиент отправляет 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
- share_errno читает последнее состояние
- 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 проверяются отдельно.
- Первый клиент посылает GET без Cookie
- Сервер отвечает Set-Cookie: theme=blue%20sky
- Cookie engine сохраняет значение в общем share
- Второй клиент отправляет 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
- Функция вернула техническое описание
- Решение об успехе принимается по коду
Этот вариант. Используется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-клиентов современный код освобождает ссылки; уже полученная тема остаётся строкой.
- Первый клиент посылает GET без Cookie
- Сервер отвечает Set-Cookie: theme=blue%20sky
- Cookie engine сохраняет значение в общем share
- Второй клиент отправляет 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-кеш живёт по отдельным правилам процесса. |
- Создали объект share
- Вызвали устаревший close; диагностируем deprecated
- Тот же объект ещё принимает настройку
Первый пример специально воспроизводит устаревший вызов на PHP8.5+. set_error_handler задаёт временную функцию обработки; она считает только E_DEPRECATED, finally восстанавливает прежнюю. use (&$deprecated) даёт этой функции доступ к тому же внешнему счётчику, а ++ увеличивает его на1. Это демонстрация миграции, а не совет подавлять предупреждения на сайте. Захват переменной замыканием.
Этот вариант. Поведение deprecated проверено именно на PHP8.5.11. На PHP8.2–8.4 no-op уже есть, но такого предупреждения ещё нет.
<?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 для него не допускаются.
- Выбран только DNS-cache
- Новый easy-клиент подключён к share
- Локальный HTTP возвращает строку товара
- Опыт не измеряет межзапросное кеширование
В архиве есть 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_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 поддержку сборки. |
- Передали DNS+CONNECT с повтором DNS
- PHP нормализует набор
- Получаем объект options с2категориями
- Другой порядок использует тот же набор кешей
Этот вариант. Проверено два разных PHP-объекта с одинаковыми нормализованными options. Реальный reuse underlying share подтверждён source; это не замер повторного TCP-соединения.
<?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 здесь только показывает неподходящий элемент. Пользовательские данные не должны выбирать произвольный кеш или объект.
<?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 возвращает текст вместо немедленного вывода.
- PHP-клиент → GET /product?id=1 → 127.0.0.1:8791
- server.php выбирает Молоток со stock8
- Сервер → HTTP200, Content-Type text/plain, тело «Молоток — 8 шт.»
- Клиент проверяет транспорт и статус, затем выводит тело
В архиве есть 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($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-ошибок здесь ещё нет. |
- curl_init → $handle
- CURLOPT_URL выбирает настройку адреса
- Строка http://127.0.0.1:8781/order/42 записывается в handle
- true → можно перейти к другим настройкам
- Сеть запустится только при 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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


