When using the curl_multi_* function in PHP, we can initiate multiple HTTP requests at the same time to improve the concurrency of the program. The curl_multi_close function is used to close all concurrent requests, but how to make sure it closes all requests correctly and avoids omissions is still a concern.
Before discussing how to properly close a request, we first need to understand how the curl_multi_* function works. The curl_multi_* series functions are mainly:
curl_multi_init() : Initialize a cURL multiple handle.
curl_multi_add_handle() : Adds the cURL handle to the multiple handle.
curl_multi_exec() : executes all requests added to the multiple handles.
curl_multi_getcontent() : Gets the return content of the specified handle.
curl_multi_close() : Close all handles added via curl_multi_add_handle() .
These functions are often used in conjunction with each other to efficiently handle multiple concurrent requests.
In the handling of multi-concurrent requests, one of the most common problems is that when curl_multi_close is called, all request handles are not closed correctly. Doing so will lead to resource leakage and affect the stability of the program.
Usually, the problem occurs in the following situations:
Forgot to check if curl_multi_exec completes all requests.
Before curl_multi_close , each handle was not removed correctly.
Improper resource management results in inconsistent shutdown handles.
To ensure that all requests are closed correctly when using curl_multi_close , we need to follow these steps:
First, we initialize a multiple handle and initialize a separate cURL handle for each request.
$mh = curl_multi_init(); // Initialize multiple handles
$ch1 = curl_init("https://gitbox.net/api/endpoint1"); // The first request
$ch2 = curl_init("https://gitbox.net/api/endpoint2"); // The second request
// Add the request handle to multiple handles
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
Next, we use curl_multi_exec to execute all requests until all requests are completed.
do {
$mrc = curl_multi_exec($mh, $active); // Execute a request
if ($active) {
curl_multi_select($mh); // Wait for the request to complete
}
} while ($active && $mrc == CURLM_OK);
Once all requests are completed, we can use curl_multi_getcontent to get the response content of each request, then remove each handle from the multiple handles, and finally close all handles.
// Get the requested content
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
// Close and remove each handle
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
// Close every request
curl_close($ch1);
curl_close($ch2);
// Finally close the multiple handles
curl_multi_close($mh);
Make sure that before calling curl_multi_close , all handles are removed correctly and that each handle is closed. This avoids resource leakage and unnecessary memory usage.
In actual development, we may encounter some request failures. To ensure that all handles can be closed correctly in exceptional situations, it is recommended to add exception catch and error handling mechanisms during execution.
// Add exception handling
try {
// Code to execute concurrent requests(As shown above)
if ($mrc != CURLM_OK) {
throw new Exception("Error in curl_multi_exec: $mrc");
}
} catch (Exception $e) {
// Catch exceptions and close resources
echo "Error: " . $e->getMessage();
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_close($ch1);
curl_close($ch2);
curl_multi_close($mh);
}
This way ensures that even if an error occurs, the program can still clean up resources correctly.
By using the curl_multi_* series of functions reasonably and following the following points, we can ensure that curl_multi_close can correctly close all concurrent requests:
Make sure to remove each handle before calling curl_multi_close .
When using curl_multi_exec , wait for all requests to complete.
Handle exceptions appropriately to avoid unclosed handles.
Through these best practices, we can better manage concurrent requests, avoid resource leaks, and improve code robustness and performance.