编程 PHP 8.5 curl_share_init_persistent:跨请求复用 cURL 共享句柄

2026-10-08 21:02:58

PHP 8.5 curl_share_init_persistent:跨请求复用 cURL 共享句柄

PHP 8.5 新增了一个持久化的 cURL 共享句柄构造函数:

curl_share_init_persistent(array $share_options): CurlSharePersistentHandle

它和 curl_share_init() 的差别在于生命周期:创建的句柄不会在 PHP 请求结束时销毁。如果内部已存在具有相同 share_options 的持久共享句柄,就直接复用该句柄。这一行为适合长生命周期 SAPI。

参数与错误

参数是一个非空的 CURL_LOCK_DATA_* 常量数组。数组里不能包含 CURL_LOCK_DATA_COOKIE,否则抛出 ValueError——请求之间共享 cookies 可能导致用户间的敏感 cookie 混淆。

会触发的错误/异常:

  • share_options 为空 → ValueError
  • 含不匹配 CURL_LOCK_DATA_* 的值 → ValueError
  • 含 CURL_LOCK_DATA_COOKIE → ValueError
  • 含非整数值 → TypeError

用法

$sh = curl_share_init_persistent([CURL_LOCK_DATA_DNS, CURL_LOCK_DATA_CONNECT]);

$ch1 = curl_init("http://example.com/");
curl_setopt($ch1, CURLOPT_SHARE, $sh);
curl_exec($ch1); // 可能复用之前 SAPI 请求的连接

$ch2 = curl_init("http://example.com/");
curl_setopt($ch2, CURLOPT_SHARE, $sh);
curl_exec($ch2); // 复用 $ch1 的连接

实现要点

函数用 share_options 在内部构造持久 ID,用户不需要自己挑 persistent_id。每组唯一的 share_options 只对应一个共享句柄,因此连接数上限要自己在 CurlHandle 上设合适的 CURLOPT_MAXCONNECTS。

返回的 CurlSharePersistentHandle 与 CurlShareHandle 内部相同,可以用于 curl_setopt,但不能用于 curl_share_setopt,以保证句柄跨请求不可变。

相等性上有个容易踩的点:

curl_share_init_persistent([CURL_LOCK_DATA_DNS]) === curl_share_init_persistent([CURL_LOCK_DATA_DNS]) // false

因为每次调用都会重建对象,只是字段相同,比较应该用 == 而不是 ===。

性能收益

除 DNS 和连接外,还可以用 CURL_LOCK_DATA_SSL_SESSION 共享 TLS 会话,从而减少 DNS 解析与 SSL 握手——这两项通常占网络耗时的 30%–70%。

RFC 见 curl_share_persistence_improvement,实现见 php-src PR #16937。

Guzzle 的支持现状

guzzle/guzzle#3307 讨论把 curl_share_init_persistent 接进 CurlHandler。维护者指出 multi-handle 场景尚未实现,而 multi-handle 恰恰是 Guzzle 最有用的部分。作者的测试表明,easy handle 设置了 CURLOPT_SHARE 之后,curl_multi_add_handle 不会覆盖该 share handle,仍会复用连接(connect_time_us=0)。

Guzzle 的计划是分两步:

  • 7.11 提供 handler 级共享,硬编码 DNS 与 SSL session;
  • 8.0 提供持久共享(DNS、connection、SSL session),分 prefer(回退到 7.11 风格)与 require(确保完整的持久共享)两种模式。

陷阱

持久句柄的生命周期跨请求,因此其适用前提是长生命周期 SAPI。短生命周期或进程模型下,请求结束后的资源回收语义与普通 curl_share_init() 不同,CURLOPT_MAXCONNECTS 之类的连接上限也需要按进程实际并发量显式设置。

链接

复制全文 生成海报 PHP cURL 性能 Guzzle 连接复用

推荐文章

程序员茄子在线接单