基礎初始化流程
<?php
$ch = curl_init();
// 必須設置
curl_setopt($ch, CURLOPT_URL, 'https://api.example.com/endpoint');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回字符串而非直接輸出
// 執行並關閉
$response = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
curl_close($ch);
?>
常用選項分類速查表
1. 請求行為控制
| 選項 | 說明 | 典型值 |
| CURLOPT_POST | 啟用 POST 請求 | 1 / true |
| CURLOPT_POSTFIELDS | POST 數據(陣列自動編碼為 multipart/form-data) | ['key' => 'val'] / http_build_query($arr) |
| CURLOPT_CUSTOMREQUEST | 自定義請求方法 | 'PUT', 'DELETE', 'PATCH' |
| CURLOPT_HTTPGET | 強制 GET 請求 | true |
2. 超時與重定向
| 選項 | 說明 | 建議值 |
| CURLOPT_CONNECTTIMEOUT | 連接階段超時(秒) | 5-10 |
| CURLOPT_TIMEOUT | 整個請求超時(秒) | 30 |
| CURLOPT_FOLLOWLOCATION | 自動跟隨 301/302 重定向 | true |
| CURLOPT_MAXREDIRS | 最大重定向次數 | 10 |
3. HTTPS/SSL 相關(開發環境常用)
| 選項 | 說明 | 注意 |
| CURLOPT_SSL_VERIFYPEER | 驗證 SSL 證書 | 生產環境必須為 true |
| CURLOPT_SSL_VERIFYHOST | 驗證域名與證書匹配 | 2 為嚴格模式 |
| CURLOPT_CAINFO | 指定 CA 證書路徑 | 解決「cacert.pem 找不到」問題 |
4. 標頭與 Cookie 管理
<?php
// 設置請求頭
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'User-Agent: MyApp/1.0',
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
'Accept: application/json',
]);
// Cookie 文件持久化
$cookieJar = sys_get_temp_dir() . '/cookies.txt';
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieJar); // 寫入
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieJar); // 讀取
// 自動攜帶 Referer
curl_setopt($ch, CURLOPT_REFERER, 'https://example.com/from-page');
curl_setopt($ch, CURLOPT_AUTOREFERER, true); // 重定向時自動更新
?>
5. 進階性能優化
| 選項 | 作用 | 場景 |
| CURLOPT_HTTP_VERSION | 指定 HTTP 版本 | CURL_HTTP_VERSION_2_0 啟用 HTTP/2 |
| CURLOPT_FORBID_REUSE | 完成後強制關閉連接 | 長連接導致服務器資源洩漏時 |
| CURLOPT_FRESH_CONNECT | 強制建立新連接 | 避免連接池污染 |
| CURLOPT_NOSIGNAL | 禁用信號傳遞 | 多線程環境必開 |
| CURLOPT_TCP_KEEPALIVE | TCP 保活 | 長連接防斷開 |
完整生產級封裝示例
<?php
class HttpClient {
private $ch;
private $defaultOpts = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 30,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_USERAGENT => 'MyApp/2.0 (+https://myapp.com)',
CURLOPT_ENCODING => 'gzip, deflate', // 自動解壓
];
public function __construct() {
$this->ch = curl_init();
curl_setopt_array($this->ch, $this->defaultOpts);
}
public function request(string $method, string $url, array $data = [], array $headers = []): array {
$opts = [CURLOPT_URL => $url, CURLOPT_CUSTOMREQUEST => strtoupper($method)];
if (in_array($method, ['POST', 'PUT', 'PATCH'])) {
$opts[CURLOPT_POSTFIELDS] = is_array($data) ? json_encode($data) : $data;
$headers[] = 'Content-Type: application/json';
}
if ($headers) $opts[CURLOPT_HTTPHEADER] = $headers;
curl_setopt_array($this->ch, $opts);
$body = curl_exec($this->ch);
$info = curl_getinfo($this->ch);
if (curl_errno($this->ch)) {
throw new RuntimeException(curl_error($this->ch), curl_errno($this->ch));
}
return [
'status' => $info['http_code'],
'headers' => $this->parseHeaders($info['header_size'] ?? 0),
'body' => json_decode($body, true) ?? $body,
'info' => $info,
];
}
private function parseHeaders(int $headerSize): array {
// 實際項目中需從 response 中切割 header 部分解析
return [];
}
public function __destruct() {
curl_close($this->ch);
}
}
?>
調試技巧
curl_getinfo($ch, CURLINFO_HEADER_OUT) 查看發送的原始請求頭
CURLOPT_VERBOSE => true + CURLOPT_STDERR => fopen('php://temp', 'w+') 捕獲詳細通訊日誌
- 使用
curl_setopt($ch, CURLOPT_HEADER, true) 讓響應包含頭部,便於調試
收藏此速查表,cURL 開發效率提升 80% 以上!