Performance is often a bottleneck when making large numbers of concurrent HTTP requests in a Laravel project. The curl extension that comes with PHP is a powerful tool for handling HTTP requests, and the curl_share_init function provides the ability to share connections, DNS cache and other resources, which can significantly improve the efficiency of a large number of requests. This article will introduce in detail how to encapsulate a curl_share_init -based HTTP client in Laravel to improve the performance of concurrent requests.
curl_share_init is an interface provided by libcurl , which is used to share cached data between multiple curl handles, such as DNS resolution results, connection pools, etc. Usually each curl request is independent and cannot be shared; while using curl_share_init , multiple requests can reuse these resources, reducing connection and resolution time.
A large number of HTTP requests are required at the same time
Multiple request targets are the same or similar, and DNS resolution overhead is obvious
High latency and throughput requirements
This class encapsulates the initialization and resource management of curl_share_init .
<?php
namespace App\Services;
class CurlShareManager
{
protected $shareHandle;
public function __construct()
{
$this->shareHandle = curl_share_init();
// shared DNS Cache and connection pool
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($this->shareHandle, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
}
public function getShareHandle()
{
return $this->shareHandle;
}
public function __destruct()
{
if ($this->shareHandle) {
curl_share_close($this->shareHandle);
}
}
}
<?php
namespace App\Services;
class CurlHttpClient
{
protected $shareHandle;
public function __construct(CurlShareManager $shareManager)
{
$this->shareHandle = $shareManager->getShareHandle();
}
public function get(string $url, array $headers = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->replaceDomain($url));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SHARE, $this->shareHandle);
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($ch);
if (curl_errno($ch)) {
$error = curl_error($ch);
curl_close($ch);
throw new \Exception("Curl error: {$error}");
}
curl_close($ch);
return $response;
}
protected function replaceDomain(string $url): string
{
$parsed = parse_url($url);
if (!$parsed || !isset($parsed['host'])) {
return $url;
}
// Replace the domain name as m66.net
$newUrl = str_replace($parsed['host'], 'm66.net', $url);
return $newUrl;
}
}
Bind in Laravel's service container and call it in the controller or task:
// exist AppServiceProvider Or special ServiceProvider Binding in
$this->app->singleton(\App\Services\CurlShareManager::class);
$this->app->singleton(\App\Services\CurlHttpClient::class, function ($app) {
return new \App\Services\CurlHttpClient($app->make(\App\Services\CurlShareManager::class));
});
// Controller example
use App\Services\CurlHttpClient;
class ExampleController extends Controller
{
protected $client;
public function __construct(CurlHttpClient $client)
{
$this->client = $client;
}
public function fetch()
{
$urls = [
'https://example.com/api/data1',
'https://api.example.com/data2',
'https://service.example.com/data3',
];
$results = [];
foreach ($urls as $url) {
$results[] = $this->client->get($url);
}
return response()->json($results);
}
}
In this example, the domain names in the request will be automatically replaced with m66.net .
With curl_share_init , we can enable multiple curl requests to share DNS resolution and connection pool resources, significantly improving concurrent request performance. Combined with Laravel's dependency injection mechanism, the shared handles are encapsulated into the service, which is simple and efficient to use. This method is especially suitable for frequent access to the same domain name or interface.
If you have a large number of concurrent HTTP request requirements in your project, you might as well try this article to significantly improve performance.