curl_setopt() 是 PHP cURL 擴展的核心配置函數,用於設定單一 cURL 會話的各種選項(URL、HTTP 方法、Header、Cookie、Proxy、SSL、超時等)。掌握常用選項是實現網路請求自動化、API 串接、模擬瀏覽器行為的關鍵。
語法
curl_setopt(CurlHandle $handle, int $option, mixed $value): bool
- $handle:
curl_init() 返回的控制代碼。
- $option:
CURLOPT_* 常數。
- $value:對應選項的值。
核心選項分類速查
行為控制
| 常數 | 值類型 | 說明 |
CURLOPT_URL | string | 請求目標 URL |
CURLOPT_RETURNTRANSFER | bool | true 返回字串,false 直接輸出(預設) |
CURLOPT_HEADER | bool | 是否在輸出中包含回應 Header |
CURLOPT_FOLLOWLOCATION | bool | 是否自動追蹤 3xx 重導向 |
CURLOPT_MAXREDIRS | int | 最大重導向次數 |
CURLOPT_AUTOREFERER | bool | 自動設定 Referer Header(重導向時) |
CURLOPT_TIMEOUT | int | 最大執行秒數(連線+傳輸) |
CURLOPT_CONNECTTIMEOUT | int | 連線階段最大秒數 |
CURLOPT_FAILONERROR | bool | HTTP 碼 ≥ 400 時返回 false |
CURLOPT_SSL_VERIFYPEER | bool | 驗證 SSL 憑證(生產環境必須 true) |
CURLOPT_SSL_VERIFYHOST | int | 驗證 SSL 憑證中的 CN(2=嚴格,生產建議 2) |
HTTP 請求設定
| 常數 | 值類型 | 說明 |
CURLOPT_POST | bool | true 發送 POST 請求 |
CURLOPT_POSTFIELDS | array|string | POST 資料(陣列自動編碼為 multipart/form-data) |
CURLOPT_HTTPHEADER | array | 自定 Header 陣列(如 ['Content-Type: application/json', 'Authorization: Bearer ...']) |
CURLOPT_USERAGENT | string | User-Agent 字串 |
CURLOPT_REFERER | string | Referer Header |
CURLOPT_CUSTOMREQUEST | string | 自定 HTTP 方法(PUT, DELETE, PATCH 等) |
CURLOPT_HTTP_VERSION | int | HTTP 版本(CURL_HTTP_VERSION_1_1, CURL_HTTP_VERSION_2_0) |
Cookie 與 Session 處理
| 常數 | 值類型 | 說明 |
CURLOPT_COOKIE | string | 直接傳送 Cookie 字串 |
CURLOPT_COOKIEJAR | string | 儲存 Cookie 到檔案(回應的 Set-Cookie) |
CURLOPT_COOKIEFILE | string | 從檔案讀取 Cookie 發送(需與 JAR 同路徑) |
檔案上傳/下載
| 常數 | 值類型 | 說明 |
CURLOPT_UPLOAD | bool | 準備上傳模式 |
CURLOPT_INFILE | resource | 上傳檔案控制代碼(fopen() 返回) |
CURLOPT_INFILESIZE | int | 上傳檔案大小(位元組) |
CURLOPT_FILE | resource | 寫入回應內容的檔案控制代碼 |
實戰:封裝通用請求函數(支援 Cookie、重導向、錯誤處理)
<?php
function vcurl(string $url, string $post = '', string $cookie = '', string $cookiejar = '', string $referer = ''): string {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT'] ?? 'PHP cURL');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 生產環境必開
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
if ($referer) {
curl_setopt($ch, CURLOPT_REFERER, $referer);
} else {
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
}
if ($post) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
if ($cookiejar) {
$path = getcwd() . '/' . $cookiejar;
curl_setopt($ch, CURLOPT_COOKIEJAR, $path);
curl_setopt($ch, CURLOPT_COOKIEFILE, $path);
}
$response = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception('cURL Error: ' . curl_error($ch));
}
curl_close($ch);
return $response;
}
// 使用範例:模擬登入並取得受保護頁面
try {
// 1. 登入(取得 Cookie)
$loginUrl = 'https://example.com/login';
$postData = ['username' => 'user', 'password' => 'pass'];
$jar = 'cookies.txt';
vcurl($loginUrl, http_build_query($postData), '', $jar);
// 2. 存取需登入的頁面(自動攜帶 Cookie)
$content = vcurl('https://example.com/dashboard', '', '', $jar);
echo $content;
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
常見陷阱與最佳實踐
- SSL 驗證:開發環境可暫時關閉,生產環境絕對不可關閉(
CURLOPT_SSL_VERIFYPEER => false 會暴露中間人攻擊風險)。
- Cookie 持久化:
COOKIEJAR / COOKIEFILE 必須指向**同一個可寫入的檔案路徑**。
- POST 欄位編碼:陣列會送出
multipart/form-data;JSON API 需手動 json_encode() 並設定 Content-Type: application/json Header。
- 資源釋放:一定要
curl_close(),長期運行腳本否則會洩漏檔案描述符。
- 錯誤處理:檢查
curl_errno()、curl_error()、HTTP 狀態碼(curl_getinfo($ch, CURLINFO_HTTP_CODE))。