When using cURL for multiple requests in PHP, the curl_multi_* series of functions can significantly improve the performance of the program, especially in the scenario of concurrent requests. However, many developers tend to ignore some key error handling and resource release issues when using these functions, especially the use of curl_multi_close . If curl_multi_close is called incorrectly, it may cause resource leakage, performance problems, and even memory overflow problems.
This article will explain in detail how to correctly use the curl_multi_close function when handling errors to avoid resource leakage and other potential problems.
The curl_multi_close function is a function in the PHP cURL extension that closes all handles initialized in a multiple cURL session. The curl_multi_* function allows multiple cURL requests to be executed in parallel, while curl_multi_close is used to properly close each cURL session after all requests are completed to free up resources.
When executing multiple concurrent requests, we need to use curl_multi_init to initialize a multi-session resource, and then use curl_multi_add_handle to add each individual cURL session to this multi-session. After the request is completed, curl_multi_close must be called to close the multi-session resource.
Code example:
// How much initializationcURLSession
$mh = curl_multi_init();
$ch1 = curl_init();
$ch2 = curl_init();
// set upcURLOptions
curl_setopt($ch1, CURLOPT_URL, "https://gitbox.net/api/endpoint1");
curl_setopt($ch2, CURLOPT_URL, "https://gitbox.net/api/endpoint2");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// 添加Session到多重Session资源中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Perform multiple requests
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
// Wait for the request to complete
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
// Get and process return data
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
// closurecURLSession
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
// 最后closure多重cURLSession
curl_multi_close($mh);
Error handling is a crucial part of multiple requests. When executing multiple requests, various errors may be encountered, including connection timeout, invalid response, server error, etc. To avoid the resource not being released when an error occurs, try-catch can be used to catch exceptions to ensure that the resource is properly closed regardless of whether the request is successful or not.
Error handling code example:
try {
// How much initializationcURLSession
$mh = curl_multi_init();
$ch1 = curl_init();
$ch2 = curl_init();
// set upcURLOptions
curl_setopt($ch1, CURLOPT_URL, "https://gitbox.net/api/endpoint1");
curl_setopt($ch2, CURLOPT_URL, "https://gitbox.net/api/endpoint2");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// 添加Session到多重Session资源中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Perform multiple requests
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
// Wait for the request to complete
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
// Check the results of each request
if ($status != CURLM_OK) {
throw new Exception("cURLRequest failed,Error code:" . $status);
}
// Get and process return data
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
// Process the returned data here...
} catch (Exception $e) {
// Error handling part:Log error log
error_log("Request failed:" . $e->getMessage());
} finally {
// Make sure there are errors or not,Resources will be released correctly
if (isset($mh)) {
// closureSession资源
if (isset($ch1)) {
curl_multi_remove_handle($mh, $ch1);
curl_close($ch1);
}
if (isset($ch2)) {
curl_multi_remove_handle($mh, $ch2);
curl_close($ch2);
}
curl_multi_close($mh);
}
}
If curl_multi_close is not called after the request is completed, the PHP session will occupy system resources, resulting in memory leaks and performance issues. In the case of multiple requests, unclosed cURL handles may accumulate over time, affecting the stability of the program, and even causing the process to crash. Therefore, it is crucial to use curl_multi_close correctly.
Resource leaks usually occur in the following situations:
Forgot to call the curl_multi_close function.
When an error occurs, the program fails to enter the finally block to release the resource.
In a loop or repeated request, a new session is created repeatedly but the old session is not closed.
The best practice to avoid these problems is to always use the try-catch-finally structure to ensure that all sessions can be closed properly even if there are errors.
Proper use of curl_multi_close is a critical step to avoid resource leakage and other performance issues. When concurrent requests, we should always pay attention to error handling and resource management. Ensuring the correct release of resources after each request through the try-catch-finally structure ensures the stability of the application in a high concurrency environment.
In actual development, we should always be careful to manage each cURL session to avoid missing the shutdown of resources in case of request failure or other errors. Only in this way can our multiple cURL requests be more efficient and stable, avoiding potential memory leaks and performance bottlenecks.