傳統做法需設定 CURLOPT_COOKIEJAR 寫入文件,再讀取 CURLOPT_COOKIEFILE,產生兩次磁碟 I/O。本文展示如何直接從響應 Header 解析 Set-Cookie,以變量形式保存,效能提升顯著。
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1); // 返回 Header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回字串而非直接輸出
$content = curl_exec($ch);
curl_close($ch);
// 分離 Header 與 Body
list($header, $body) = explode("\r\n\r\n", $content, 2);
// 正則提取所有 Set-Cookie
preg_match_all('/^Set-Cookie:\s*([^;]+)/mi', $header, $matches);
$cookies = [];
foreach ($matches[1] as $cookie) {
$cookies[] = trim($cookie);
}
$cookieString = implode('; ', $cookies); // 供下次請求使用
// 後續請求直接帶入
// curl_setopt($ch, CURLOPT_COOKIE, $cookieString);
| 步驟 | 關鍵選項/函數 | 說明 |
|---|---|---|
| 獲取 Header | CURLOPT_HEADER => 1 | 使 curl_exec 返回「Header + Body」 |
| 分離 Header/Body | explode("\r\n\r\n", $content, 2) | 限制分割次數為 2,避免 Body 含雙換行被誤切 |
| 提取 Cookie | preg_match_all('/^Set-Cookie:\s*([^;]+)/mi', ...) | m 多行模式,i 忽略大小寫,捕獲 ; 前內容 |
| 後續使用 | CURLOPT_COOKIE => $cookieString | 直接以字串發送,無需文件 |
function curl_exec_with_cookies($url, $postData = null, $cookieString = '') {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HEADER => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_COOKIE => $cookieString,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 15,
]);
if ($postData) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
}
$content = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
list($header, $body) = explode("\r\n\r\n", $content, 2);
preg_match_all('/^Set-Cookie:\s*([^;]+)/mi', $header, $m);
$newCookies = implode('; ', $m[1]);
return ['header' => $header, 'body' => $body, 'cookies' => $newCookies, 'info' => $info];
}
// 使用:登入 -> 取得 Cookie -> 後續請求
$r1 = curl_exec_with_cookies('https://site.com/login', ['user'=>'a','pwd'=>'b']);
$r2 = curl_exec_with_cookies('https://site.com/profile', null, $r1['cookies']);
COOKIEJAR 文件持久化,避免進程重啟丟失 Cookie。此技巧將 Cookie 管理從文件 I/O 解脫,讓 cURL 流程更輕量、更適合無狀態微服務調用鏈。