在使用 PHP 的 cURL 库进行网络请求时,通常我们会创建独立的 cURL 句柄(curl_init())来进行操作。然而,当我们需要在多个 cURL 句柄之间共享某些数据(如 Cookie、DNS 缓存或 SSL 会话等)时,curl_share_init() 和 curl_share_setopt() 就派上了用场。
本文将详细解析如何使用这些函数,以及如何通过 CURLSHOPT_SHARE 和 CURLSHOPT_UNSHARE 实现资源共享与取消共享机制。
在 cURL 中,每个 cURL 句柄默认是独立的。如果你需要让多个句柄共享某些内部数据(比如 DNS 解析缓存、Cookie 数据或 SSL 会话缓存),就可以使用“共享句柄”(share handle)。
PHP 提供以下几个相关函数:
curl_share_init():初始化一个共享句柄。
curl_share_setopt():为共享句柄设置共享选项。
curl_share_close():关闭共享句柄。
对应的选项:
CURLSHOPT_SHARE:指定要共享的资源类型。
CURLSHOPT_UNSHARE:指定要取消共享的资源类型。
假设我们有两个不同的 cURL 请求,我们希望它们共享同一份 Cookie 数据。这样,第一个请求设置的 Cookie,第二个请求就可以自动使用。
<?php
// 初始化共享句柄
$sh = curl_share_init();
// 设置共享的内容,这里我们共享 Cookie
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
// 初始化第一个 cURL 句柄
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, "https://m66.net/page1");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_SHARE, $sh);
$response1 = curl_exec($ch1);
curl_close($ch1);
// 初始化第二个 cURL 句柄
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, "https://m66.net/page2");
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_SHARE, $sh);
$response2 = curl_exec($ch2);
curl_close($ch2);
// 取消共享 Cookie
curl_share_setopt($sh, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE);
// 关闭共享句柄
curl_share_close($sh);
// 输出结果
echo "Response 1:\n$response1\n";
echo "Response 2:\n$response2\n";
?>
1?? curl_share_init()
我们先调用 curl_share_init() 创建一个共享句柄 $sh,这个句柄专门用来管理要共享的数据。
2?? curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE)
这里我们指定共享 Cookie 数据。CURL_LOCK_DATA_COOKIE 表示 cookie 数据,其他可用值包括:
CURL_LOCK_DATA_DNS(DNS 缓存)
CURL_LOCK_DATA_SSL_SESSION(SSL 会话)
你可以多次调用 curl_share_setopt() 来共享多种数据。
3?? CURLOPT_SHARE
每个 cURL 句柄($ch1、$ch2)都要通过 CURLOPT_SHARE 绑定到共享句柄 $sh,这样它们才能共享指定的数据。
4?? curl_share_setopt($sh, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE)
当不再需要共享某个数据时,可以用 CURLSHOPT_UNSHARE 指定取消共享。注意:UNSHARE 仅取消共享该类型数据,但共享句柄仍可继续用。
5?? curl_share_close($sh)
最后,释放共享句柄资源。注意,这一步是必须的,否则可能导致内存泄漏。
共享句柄只在同一个进程内有效。
不是所有数据类型都适合共享,实际应用时需要结合具体场景。
在多线程环境下使用共享句柄需要格外小心,确保线程安全。