Current Location: Home> Latest Articles> Use curl_multi_close to avoid repeated closing of connections in asynchronous requests

Use curl_multi_close to avoid repeated closing of connections in asynchronous requests

gitbox 2025-05-13

In PHP, cURL is a powerful library that allows us to send requests through multiple protocols, such as HTTP, HTTPS, FTP, etc. The curl_multi_* series of functions allow us to issue multiple asynchronous requests at the same time, thereby improving performance and reducing request time. Asynchronous requests are very useful especially when multiple HTTP requests are required.

However, when using the curl_multi_* function for asynchronous requests, there is a common pitfall: repeatedly closing connections . When we close a cURL session through the curl_multi_close function, if the connection is not properly managed, some connections may be repeatedly closed before they are not properly closed, causing an error or memory leak.

This article will show you how to properly use curl_multi_close in PHP to manage asynchronous requests and avoid repeated closing of connections.

1. Basic steps to use curl_multi_* function

First, let's take a look at how to use PHP's curl_multi_* series function to initiate multiple asynchronous requests. Here is a basic example:

 <?php
// Create multiple cURL Session
$ch1 = curl_init();
$ch2 = curl_init();

// set up cURL Request Options
curl_setopt($ch1, CURLOPT_URL, 'https://gitbox.net/api/endpoint1');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_URL, 'https://gitbox.net/api/endpoint2');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);

// create cURL Multiple handles
$mh = curl_multi_init();

// Put each cURL Session加入Multiple handles
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

// Perform asynchronous requests
do {
    $status = curl_multi_exec($mh, $active);
} while ($active);

// Get the result of each request
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);

// Output result
echo "Response 1: " . $response1 . "\n";
echo "Response 2: " . $response2 . "\n";

// 关闭Session
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
curl_close($ch1);
curl_close($ch2);
?>

In this example, we create two cURL sessions and set up the request URL, and use the curl_multi_* function to issue two asynchronous requests at the same time. curl_multi_exec will run until all requests are completed. Then we use curl_multi_getcontent to get the return result and finally close all sessions.

2. Avoid repeated closing of connections

In the above code, we used curl_multi_close to close cURL multi-handle and used curl_close to close each individual cURL session. This is a common practice, but it should be noted that curl_multi_close is only responsible for closing multiple handles and does not close each session handle. So after closing curl_multi_close , each curl_close still needs to be closed via curl_close .

Problem: If you repeatedly call curl_close or curl_multi_close in some cases, you may have the problem of repeated closing of the connection. To avoid this, we can take two methods:

  1. Make sure each handle is closed only once <br> During loops or processing, we may accidentally close certain sessions repeatedly. To avoid this problem, you can make a mark when closing, making sure each handle is closed only once.

  2. Remove the handle first and then close it <br> Use curl_multi_remove_handle to remove the handle, making sure each handle is removed from the multiple handles when closed. This avoids the closed handles appearing when curl_multi_close is called.

3. Improved code examples

To avoid repeated closing of connections, we have improved the code:

 <?php
// Create multiple cURL Session
$ch1 = curl_init();
$ch2 = curl_init();

// set up cURL Request Options
curl_setopt($ch1, CURLOPT_URL, 'https://gitbox.net/api/endpoint1');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_URL, 'https://gitbox.net/api/endpoint2');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);

// create cURL Multiple handles
$mh = curl_multi_init();

// Put each cURL Session加入Multiple handles
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

// Perform asynchronous requests
do {
    $status = curl_multi_exec($mh, $active);
} while ($active);

// Get the result of each request
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);

// Output result
echo "Response 1: " . $response1 . "\n";
echo "Response 2: " . $response2 . "\n";

// 移除句柄后再关闭Session
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);

// Close correctly
curl_multi_close($mh);
curl_close($ch1);
curl_close($ch2);
?>

4. Summary

  1. Use the curl_multi_* function to effectively initiate multiple asynchronous requests to improve performance.

  2. When closing a cURL session, be sure to use curl_multi_remove_handle to remove the session, and then call curl_multi_close .

  3. Each cURL session should be closed via curl_close before closing, avoiding repeated closing in curl_multi_close .

By correctly managing the closure of connections, we can avoid repeated closures of connections, ensuring that the code is more stable and efficient.