在使用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)
最後,釋放共享句柄資源。注意,這一步是必須的,否則可能導致內存洩漏。
共享句柄只在同一個進程內有效。
不是所有數據類型都適合共享,實際應用時需要結合具體場景。
在多線程環境下使用共享句柄需要格外小心,確保線程安全。