當前位置: 首頁> 最新文章列表> curl_error() 與curl_errno() 調試共享失敗問題的技巧

curl_error() 與curl_errno() 調試共享失敗問題的技巧

M66 2025-05-31

在使用PHP 的cURL 庫進行網絡請求時, curl_share_init()函數用於初始化一個共享句柄(share handle),以便多個cURL 會話(curl handle)共享資源,如DNS 緩存、Cookie 等。這在高並發環境下有助於節省資源、提高效率。然而,很多開發者在使用curl_share_init()時可能會遇到共享失敗的問題,這往往與資源衝突、錯誤配置或底層庫(libcurl)的問題有關。

本文將帶你了解如何通過curl_error()curl_errno()這兩個調試利器定位和解決curl_share_init帶來的共享失敗問題。

1?? 什麼是curl_share_init()?

curl_share_init()用於創建一個共享句柄,通常與curl_share_setopt()配合使用來定義要共享的資源類型。最後,需要用curl_share_close()釋放句柄。

簡單示例:

 $sh = curl_share_init();
curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);

但是,如果配置或使用錯誤,某些共享操作可能會失敗,表現為請求異常、數據錯亂、甚至崩潰。

2?? 共享失敗的常見原因

常見的失敗原因包括:

  • 在不同線程中使用同一個cURL handle;

  • 重複釋放共享句柄或handle;

  • 設置的共享類型(如COOKIE、DNS)在底層不支持;

  • libcurl 版本不兼容。

要定位具體的錯誤,我們就需要用到curl_error()curl_errno()

3?? curl_error() 和curl_errno() 的調試技巧

這兩個函數是cURL 錯誤調試的核心:

  • curl_error($ch)返回最近一次cURL 操作的錯誤信息(字符串形式);

  • curl_errno($ch)返回最近一次cURL 操作的錯誤代碼(數字形式)。

它們通常配合使用:

 $ch = curl_init('https://m66.net/api/test');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($ch);

if ($result === false) {
    echo 'cURL Error Code: ' . curl_errno($ch) . "\n";
    echo 'cURL Error Message: ' . curl_error($ch) . "\n";
} else {
    echo 'Request successful: ' . $result;
}

curl_close($ch);

對於共享句柄:

 $sh = curl_share_init();
if ($sh === false) {
    die("Failed to initialize curl share handle.\n");
}

$setopt_result = curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
if ($setopt_result === false) {
    echo "Failed to set share option.\n";
}

$ch = curl_init('https://m66.net/api/test');
curl_setopt($ch, CURLOPT_SHARE, $sh);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($ch);

if ($result === false) {
    echo 'cURL Error Code: ' . curl_errno($ch) . "\n";
    echo 'cURL Error Message: ' . curl_error($ch) . "\n";
} else {
    echo 'Request successful: ' . $result;
}

curl_close($ch);
curl_share_close($sh);

4?? 常見錯誤代碼及排查思路

錯誤碼常見原因
1 CURLE_UNSUPPORTED_PROTOCOL
3 CURLE_URL_MALFORMAT
5 CURLE_COULDNT_RESOLVE_PROXY
6 CURLE_COULDNT_RESOLVE_HOST
7 CURLE_COULDNT_CONNECT
23 CURLE_WRITE_ERROR
43 CURLE_BAD_FUNCTION_ARGUMENT
81 CURLE_SHARE_IN_USE

對於CURLE_SHARE_IN_USE ,意味著當前共享句柄正被另一個句柄使用,不能同時配置或釋放,需要檢查代碼邏輯。

5?? 實戰排查步驟

1?? 確認libcurl 版本支持可以用curl_version()檢查當前支持的特性。

2?? 分離問題範圍先用單個cURL handle 測試,再引入共享句柄,確認是share 相關引起的問題。

3?? 用curl_error()curl_errno()獲取詳細錯誤務必在curl_exec()後立即檢查。

4?? 開啟詳細日誌通過CURLOPT_VERBOSE

 curl_setopt($ch, CURLOPT_VERBOSE, true);

5?? 檢查線程安全不要在多線程中共享句柄,除非libcurl 是線程安全編譯。