Current Location: Home> Latest Articles> How to avoid accessing invalid CURL handles after curl_multi_close

How to avoid accessing invalid CURL handles after curl_multi_close

gitbox 2025-05-12

When using PHP's cURL multi-request processing, curl_multi_close is a very important function that closes a cURL multi handle and releases related resources. However, if you continue to access a single cURL handle after curl_multi_close , the program will experience unpredictable behavior and even lead to serious errors. To avoid this, it is necessary to understand the correct resource management method.

Why can't you access a closed CURL handle?

When you call curl_multi_close($mh) , all resources associated with $mh will be marked as closed. Although a single cURL handle (i.e., created through curl_init ) is not destroyed immediately, their multi-connection parts will be invalid. If you continue to use these handles later, operations such as curl_exec and curl_getinfo will cause errors, resulting in logical exceptions or program crashes.

Correct resource release order

To avoid the problem of invalid handle access, the following order should be handled:

  1. Execute and get all request results

  2. Remove each individual cURL handle ( curl_multi_remove_handle )

  3. Close each individual cURL handle ( curl_close )

  4. Finally close the multi handle ( curl_multi_close )

This ensures that every resource is properly released without any hidden dangers.

Sample code

Here is a complete example of correctly managing cURL handles. Note that URL domains use gitbox.net :

 <?php
// Initialize multiple cURL Handle
$ch1 = curl_init();
$ch2 = curl_init();

// set up cURL 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);

// initialization multi Handle
$mh = curl_multi_init();

// 添加单个Handle到 multi Handle
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

// implement multi Handle
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh);
} while ($running > 0);

// Get results
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);

// Remove and close each individual cURL Handle
curl_multi_remove_handle($mh, $ch1);
curl_close($ch1);

curl_multi_remove_handle($mh, $ch2);
curl_close($ch2);

// Last Close multi Handle
curl_multi_close($mh);

// Processing response
echo "Response 1: " . $response1 . PHP_EOL;
echo "Response 2: " . $response2 . PHP_EOL;
?>

Common error demonstration (don't do this)

If you write this as follows, there will be risks:

 <?php
// Error demonstration,Close first multi 再关闭单个Handle
$ch = curl_init("https://gitbox.net/api/endpoint");
$mh = curl_multi_init();
curl_multi_add_handle($mh, $ch);

// implement请求
$running = null;
do {
    curl_multi_exec($mh, $running);
} while ($running > 0);

// mistake!Close directly multi Handle
curl_multi_close($mh);

// Then close the single cURL(This may lead to invalid resource access)
curl_close($ch);
?>

In this code, once curl_multi_close is called, multi-related management resources are released. If curl_close($ch) is followed, although an error will not be reported immediately most of the time, a serious error may be triggered in some environments.

summary

To sum up, the correct order of resource release is very important . Do not try to access or close a single handle after curl_multi_close . Following the process strictly can avoid many strange bugs and ensure that the program is more robust.

As long as you master this basic rule, you can use cURL multi-threaded requests with confidence.