Current Location: Home> Latest Articles> How do I make sure that all open cURL handles are closed when using curl_close?

How do I make sure that all open cURL handles are closed when using curl_close?

gitbox 2025-05-20

Using cURL for network requests in PHP is a very common practice, especially when you need to communicate with external APIs. However, if you do not close used cURL handles correctly, it may cause memory leaks or waste of resources. This article will explain in detail how to correctly use the curl_close function to ensure that all open handles are closed correctly, especially when making concurrent requests or loop operations.

Basic cURL usage

In the most basic usage scenario, closing the cURL handle is relatively simple:

 $ch = curl_init('https://gitbox.net/api/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);

This code closes the handle using curl_close immediately after the request is completed, which is recommended.

Using cURL in a loop: An easy-to-ignore pitfall

When you need to send multiple requests, you usually use a loop, and it is easy to miss the closing handle:

 $urls = [
    'https://gitbox.net/api/user/1',
    'https://gitbox.net/api/user/2',
    'https://gitbox.net/api/user/3',
];

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    // If you forget curl_close($ch),Each iteration leaves a resource that is not released
}

In this case, the handle must be manually closed after each iteration:

 foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch); // Make sure to close the handle
}

Correct way to close when using multithreading (curl_multi_*)

If you are using curl_multi_init to implement concurrent requests, then the order of closing handles needs to be paid attention to:

 $multiHandle = curl_multi_init();
$curlHandles = [];

$urls = [
    'https://gitbox.net/api/task/1',
    'https://gitbox.net/api/task/2',
    'https://gitbox.net/api/task/3',
];

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multiHandle, $ch);
    $curlHandles[] = $ch;
}

// Perform concurrent requests
$running = null;
do {
    curl_multi_exec($multiHandle, $running);
    curl_multi_select($multiHandle);
} while ($running > 0);

// Remove and close all handles
foreach ($curlHandles as $ch) {
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch); // Here are the key steps to shut down
}

curl_multi_close($multiHandle);

Note that in addition to curl_close($ch) here, you must first call curl_multi_remove_handle to remove the handle to be safely closed.

Automated resource cleaning: Use function encapsulation

To avoid manually forgetting to close the handle, you can encapsulate the request process in a function to ensure that the resource is closed at the end of the function:

 function fetchUrl($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch); // Ensure that the resource is closed inside the function
    return $response;
}

$data = fetchUrl('https://gitbox.net/api/config');

Summary of suggestions

  1. Always call curl_close() to close the handle , even if the request fails.

  2. Don't miss curl_close when using multiple handle concurrency .

  3. If you use curl_multi_* , make sure to use curl_multi_remove_handle first and then curl_close .

  4. Encapsulate the request logic into functions as much as possible to ensure that the cleaning work is done internally and reduce the risk of omissions.

Correctly releasing resources can not only improve the efficiency and robustness of the script, but also avoid the risk of resource leakage on the server. It is especially important in scenarios where multi-threaded or large-scale requests are requested. With good coding habits and structural design, it is easy to ensure that every cURL handle is closed correctly.