Curl close: примеры (PHP)

Использование curl_close для завершения сеансов cURL
Раздел: Сетевые функции (cURL)
curl_close(CurlHandle $handle): void

Описание функции curl_close

Функция curl_close() в PHP предназначена для завершения сеанса cURL и освобождения всех ресурсов, связанных с переданным дескриптором cURL. Эта функция используется после выполнения всех необходимых операций с cURL-сессией.

Назначение и использование

Функция вызывается, когда завершается работа с cURL-дескриптором, созданным функцией curl_init(). После вызова curl_close() дескриптор становится недействительным, и его повторное использование невозможно.

Аргументы функции

Функция принимает один обязательный параметр:

  • $handle (ресурс) — Дескриптор cURL, возвращаемый функцией curl_init().
Примеры использования curl_close
Базовый пример с закрытием соединения

Простой пример выполнения GET-запроса и закрытия сессии.

<?php
$ch = curl_init('https://api.example.com/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if ($response === false) {
    echo 'Ошибка: ' . curl_error($ch);
}
curl_close($ch);
?>
// Результат: соединение закрыто, ресурсы освобождены.
Закрытие с проверкой существования дескриптора

Пример с проверкой, является ли переменная ресурсом cURL, перед закрытием.

<?php
$ch = curl_init('https://example.com');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10
]);
$data = curl_exec($ch);
if (is_resource($ch)) {
    curl_close($ch);
    echo 'Сессия корректно закрыта.';
}
?>
Сессия корректно закрыта.
Похожие функции в PHP
curl_reset

Функция curl_reset() сбрасывает все опции, установленные для дескриптора cURL, к значениям по умолчанию. Она не закрывает сессию, что позволяет повторно использовать тот же дескриптор для нового запроса. Предпочтительнее использовать, когда необходимо выполнить несколько последовательных запросов с разными настройками, не создавая новый дескриптор.

Автоматическое освобождение ресурсов

Дескриптор cURL, будучи ресурсом, автоматически закрывается при отсутствии ссылок на него (например, при выходе переменной из области видимости). Однако явный вызов curl_close() рекомендуется для детерминированного управления ресурсами.

Типичные ошибки
Повторное закрытие дескриптора

Попытка закрыть уже закрытый или несуществующий дескриптор вызывает предупреждение.

<?php
$ch = curl_init();
curl_close($ch);
curl_close($ch); // Вторая попытка закрыть
?>
Warning: curl_close(): supplied resource is not a valid cURL handle resource
Использование дескриптора после закрытия

После вызова curl_close() дескриптор становится недействительным.

<?php
$ch = curl_init('https://example.com');
curl_close($ch);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Ошибка
?>
Warning: curl_setopt(): supplied resource is not a valid cURL handle resource
Пропуск закрытия при длительных скриптах

В долго работающих скриптах (например, воркерах) пропуск curl_close() может привести к утечке ресурсов.

Изменения в последних версиях PHP
PHP 8.0: преобразование ресурсов в объекты

Начиная с PHP 8.0, дескрипторы cURL стали объектами CurlHandle вместо ресурсов. Функция curl_close() всё ещё работает, но теперь принимает объект CurlHandle. Тип параметра изменён с resource на CurlHandle. Повторный вызов функции с тем же объектом не вызывает ошибки.

// PHP 8+
$ch = curl_init();
var_dump($ch); // object(CurlHandle)#1
curl_close($ch); // Корректно работает
curl_close($ch); // Не вызывает ошибки
Расширенные примеры использования
Закрытие множества дескрипторов в цикле

При работе с несколькими одновременными запросами через curl_multi_init(), закрытие отдельных дескрипторов происходит после завершения всех операций.

Пример php
<?php
$urls = ['https://api.example.com/1', 'https://api.example.com/2'];
$multiHandle = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multiHandle, $ch);
    $handles[] = $ch;
}
// Выполнение многопоточных запросов
$running = null;
do {
    curl_multi_exec($multiHandle, $running);
} while ($running);
// Закрытие отдельных дескрипторов
foreach ($handles as $ch) {
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}
curl_multi_close($multiHandle);
?>
Использование в пользовательской функции-обёртке

Создание функции, которая автоматически закрывает дескриптор после выполнения.

Пример php
<?php
function fetchUrl(string $url): ?string {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true
    ]);
    $result = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);
    return $error ? null : $result;
}
$data = fetchUrl('https://example.com');
?>
Закрытие дескриптора в обработчике исключений

Гарантированное закрытие соединения даже при возникновении ошибки.

Пример php
<?php
$ch = curl_init('https://example.com');
try {
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    if ($result === false) {
        throw new Exception(curl_error($ch));
    }
    // Обработка результата
} finally {
    curl_close($ch); // Всегда выполняется
}
?>
Альтернативы в других языках программирования
Python: close() у объектов Session

В библиотеке requests сессия может быть закрыта методом close(), но чаще используется контекстный менеджер.

import requests
with requests.Session() as session:
    response = session.get('https://api.example.com')
# Соединение автоматически закрывается
JavaScript (Node.js): .destroy() у агента

В Node.js с модулем https или http можно явно уничтожить агент.

const https = require('https');
const req = https.request(options, (res) => {
    // обработка ответа
});
req.end();
// Явное уничтожение не требуется, сборщик мусора управляет ресурсами.
MySQL: CLOSE для курсоров

В MySQL, при работе с курсорами, используется инструкция CLOSE для освобождения ресурсов.

DECLARE cur CURSOR FOR SELECT * FROM table;
OPEN cur;
-- работа с данными
CLOSE cur;

PHP curl_close function comments

En
Curl close Close a cURL session