Frequent initialization and release of cURL resources can cause performance waste when making high concurrent HTTP requests in PHP, especially when it involves a large number of concurrent connections. To solve this problem, the curl_share_init function provides a way to share specific resources, such as DNS cache, cookies, etc., thereby improving execution efficiency in multi-threaded or multi-process environments.
This article will introduce how to use the curl_share_init function and encapsulate it in an object-oriented manner to implement an efficient shared resource pool management mechanism.
curl_share_init() is a function provided by libcurl to initialize a shared handle. It allows multiple cURL handles to share the following resources:
Cookie Data
DNS Cache
SSL session information
Connection pool
The key to sharing resources is to use curl_setopt to set a shared handle for each cURL handle:
curl_setopt($ch, CURLOPT_SHARE, $shareHandle);
The shared handle itself is created by curl_share_init() and configured through curl_share_setopt() .
We can design a simple shared resource pool management class that encapsulates the creation, management and destruction of shared handles, and supports reuse in a multi-threaded environment.
class CurlSharePool
{
private static $instance = null;
private $shareHandle;
private function __construct()
{
$this->shareHandle = curl_share_init();
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getShareHandle()
{
return $this->shareHandle;
}
public function __destruct()
{
if ($this->shareHandle) {
curl_share_close($this->shareHandle);
}
}
}
Here is an example of sending multiple HTTP requests using a shared resource pool:
$urls = [
"https://m66.net/api/v1/data1",
"https://m66.net/api/v1/data2",
"https://m66.net/api/v1/data3"
];
$share = CurlSharePool::getInstance()->getShareHandle();
$multiHandle = curl_multi_init();
$curlHandles = [];
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SHARE, $share);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[] = $ch;
}
$running = null;
do {
curl_multi_exec($multiHandle, $running);
curl_multi_select($multiHandle);
} while ($running > 0);
foreach ($curlHandles as $ch) {
$response = curl_multi_getcontent($ch);
echo $response . PHP_EOL;
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
curl_multi_close($multiHandle);
The biggest advantage of using shared handles is that it avoids re-parsing DNS and re-establishing SSL connections per request, which can significantly improve efficiency in high concurrency scenarios. Using encapsulation classes can simplify resource management, avoid resource leakage, and be more conducive to later maintenance and expansion.
Although curl_share_init is not common in PHP, it provides a low-cost optimization method in systems with high performance requirements. By encapsulating the object management model of shared handles, we can achieve more efficient and stable resource reuse, thereby improving the response speed and concurrency capabilities of the overall system.
In practical applications, this type can be further expanded, such as introducing a thread lock mechanism to ensure thread safety, supporting policy configurations of multiple resource types, etc. I hope this article can provide practical reference and inspiration for your high-performance PHP development.