Current Location: Home> Latest Articles> How to correctly end long-running requests with curl_multi_close

How to correctly end long-running requests with curl_multi_close

gitbox 2025-05-12

In PHP, the curl_multi_* series of functions provide a powerful way to initiate multiple HTTP requests at the same time, thereby improving the concurrency performance of the program. Among them, curl_multi_close() is a function used to clean up resources. It is called after all concurrent requests are completed and is an important step in releasing the underlying resources. However, if used improperly, it may cause memory leaks or the request is not completely terminated.

This article will use actual code examples to explain how to correctly use curl_multi_close() to end long-running requests.

1. What is curl_multi_close?

curl_multi_close() is the final function paired by curl_multi_init() . Its purpose is to close a multi handle resource and release all resources associated with it. Note that it does not automatically close each individual curl handle added to this multi handle, so we need to handle it manually.

2. A basic example of concurrent requests

Here is a standard process for executing multiple HTTP requests using the curl_multi_* series of functions and correctly closing resources:

 <?php

// Create the requested URL Array
$urls = [
    'https://gitbox.net/api/endpoint1',
    'https://gitbox.net/api/endpoint2',
    'https://gitbox.net/api/endpoint3',
];

// initialization multi handle
$multiHandle = curl_multi_init();
$curlHandles = [];

// For each URL initialization单独的 curl handle and add to multi handle middle
foreach ($urls as $i => $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($multiHandle, $ch);
    $curlHandles[$i] = $ch;
}

// Perform all requests
$running = null;
do {
    $status = curl_multi_exec($multiHandle, $running);
    if ($running) {
        curl_multi_select($multiHandle); // avoid CPU Too high occupancy
    }
} while ($running && $status == CURLM_OK);

// Process the results and close each curl handle
foreach ($curlHandles as $ch) {
    $response = curl_multi_getcontent($ch);
    $info = curl_getinfo($ch);
    echo "Request status code: " . $info['http_code'] . "\n";
    echo "Response content: " . substr($response, 0, 100) . "...\n"; // Show only some content
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}

// Last Close multi handle
curl_multi_close($multiHandle);

3. Common errors and solutions

  1. Error: Close multi handle without removing handle

     // Wrong usage
    curl_close($ch);  // Close first curl handle
    curl_multi_close($mh);
    

    The correct order should be:

     curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
    curl_multi_close($mh);
    
  2. Error: Not waiting for all requests to complete

    Some developers will skip curl_multi_select() directly or close it directly after curl_multi_exec() once, resulting in some requests not being completed. Using a do-while loop is a reliable way to ensure that all requests are completed.

4. What should be done when the request takes a long time?

For long-running requests (such as downloading large files or remote calculations), the following methods can be controlled:

  • Set a reasonable CURLOPT_TIMEOUT

  • Use curl_multi_select() to reduce CPU usage

  • Check and process the status returned by curl_multi_info_read()

Example (adding timeout control):

 curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Set the maximum execution time to30Second

5. Summary

curl_multi_close() itself is not complicated, but it must be used with curl_multi_remove_handle() and curl_close() to ensure that the resource is completely released. In high concurrency request scenarios, closing curl handles standardizedly is the key to avoid resource leakage and improving program stability.

When using multithreaded network requests, keep in mind the following order:

  1. Add a single handle to a multi handle

  2. Execute multi handle

  3. Get results

  4. Remove and close a single handle

  5. Finally close multi handle

Through the above method, you can efficiently use the curl_multi_* series functions and correctly end all connections to improve the maintainability and operation efficiency of your code.