首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP cURL 免檔案獲取 Cookie 的高效方法

     編輯:PHP 綜合知識

痛點分析

傳統 cURL 處理 Cookie 需指定 CURLOPT_COOKIEJAR 和 CURLOPT_COOKIEFILE 指向實體檔案,涉及兩次磁碟 I/O(寫入讀取),效能較差且不利於無狀態部署環境(如 Serverless、容器化)。

核心解法:記憶體中直接解析 Header

啟用 CURLOPT_HEADER 獲取原始回應,手動分離 Header 與 Body,用正則提取 Set-Cookie 欄位,後續請求直接帶入 CURLOPT_COOKIE 參數。

完整實作程式碼

// 1. 初始化 cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

// 2. 關鍵設定:獲取完整 Header、回傳原始字串
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// 3. 執行請求
$content = curl_exec($ch);
curl_close($ch);

// 4. 解析 HTTP 回應:分離 Header 與 Body
list($header, $body) = explode("\r\n\r\n", $content, 2);

// 5. 正則提取 Set-Cookie(支援多組 Cookie)
preg_match_all("/set\-cookie:\s*([^\r\n]*)/i", $header, $matches);

// 6. 組裝 Cookie 字串供下次請求使用
$cookies = array();
foreach ($matches[1] as $cookie) {
    // 僅取 name=value 部分,捨棄 path、domain、expires 等屬性
    $pair = explode(';', $cookie)[0];
    $cookies[] = trim($pair);
}
$cookieString = implode('; ', $cookies);

// 7. 後續請求直接帶入
// curl_setopt($ch, CURLOPT_COOKIE, $cookieString);

進階封裝:Cookie 管理類別

class CurlCookieJar {
    private $cookies = array();
    
    public function extractFromHeader($header) {
        preg_match_all("/set\-cookie:\s*([^\r\n]*)/i", $header, $matches);
        foreach ($matches[1] as $raw) {
            $parts = explode(';', $raw);
            $nameVal = trim($parts[0]);
            if (strpos($nameVal, '=') !== false) {
                list($name, $value) = explode('=', $nameVal, 2);
                $this->cookies[$name] = $value;
            }
        }
    }
    
    public function getCookieString() {
        $pairs = array();
        foreach ($this->cookies as $name => $value) {
            $pairs[] = "$name=$value";
        }
        return implode('; ', $pairs);
    }
    
    public function clear() { $this->cookies = array(); }
}

// 使用範例
$jar = new CurlCookieJar();
$ch = curl_init($loginUrl);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $loginData);
$resp = curl_exec($ch);
$jar->extractFromHeader($resp);

// 後續請求
$ch2 = curl_init($apiUrl);
curl_setopt($ch2, CURLOPT_COOKIE, $jar->getCookieString());
// ...

優缺點對比

維度檔案模式記憶體模式
I/O 操作2 次磁碟讀寫零磁碟 I/O
效能較慢極快
持久化自動跨程序需自行序列化儲存
並發安全需檔案鎖天然隔離
適用場景長期會話、CLI 常駐短鏈路 API 串接、Serverless

注意事項

  • 此法僅適用於同一執行緒內的連續請求,跨程序需自行序列化 $jar->getCookieString() 存入 Redis/資料庫
  • 正則未處理 Cookie 屬性(Domain、Path、Secure、HttpOnly),若目標站嚴格驗證路徑需額外解析
  • HTTPS 站點需確保 CURLOPT_SSL_VERIFYPEER 正確設定

此技巧在 API 串接、第三方登入、爬蟲登入維持會話等場景極為實用,建議封裝為工具類複用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved