| 能力 | file_get_contents | cURL |
|---|---|---|
| HTTP 方法 | 僅 GET | GET/POST/PUT/DELETE/HEAD/PATCH 任意 |
| 自定義 Header | 需 stream context,繁瑣 | CURLOPT_HTTPHEADER 直觀 |
| Cookie 管理 | 極難 | CURLOPT_COOKIEJAR/FILE 自動 |
| 檔案上傳 | 不支援 | CURLOPT_POSTFIELDS + CURLFile |
| 斷點續傳/大檔下載 | 全量載入記憶體 | CURLOPT_WRITEFUNCTION 邊寫邊收 |
| 代理/認證/SSL | 不支援/極難 | 完整支援 |
| 錯誤細節 | 僅 true/false | curl_errno()/curl_error()/curl_getinfo() |
| 並發請求 | 不支援 | curl_multi_* 原生支援 |
<?php
$ch = curl_init(); // 1. 初始化
curl_setopt_array($ch, [ // 2. 設定選項(陣列批量更優雅)
CURLOPT_URL => 'https://api.example.com/users',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_TIMEOUT => 10,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_USERAGENT => 'MyApp/1.0 (+https://example.com)',
CURLOPT_SSL_VERIFYPEER => true, // 生產環境必開
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($ch); // 3. 執行
if ($response === false) { // 4. 錯誤處理(注意 ===)
throw new \RuntimeException('cURL error: ' . curl_error($ch), curl_errno($ch));
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); // 釋放資源
<?php
// 表單
$postData = ['name' => 'John', 'action' => 'submit'];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
// JSON API
$jsonData = json_encode(['site' => 'example', 'url' => 'https://example.com']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($jsonData),
]);
<?php
$filePath = '/path/to/image.jpg';
$postFields = [
'file' => new CURLFile($filePath, 'image/jpeg', 'avatar.jpg'),
'user_id' => 123,
];
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
// 注意:使用 CURLFile 時 CURLOPT_SAFE_UPLOAD 預設 true,無需額外設定
<?php
$url = 'https://speed.hetzner.de/100MB.bin';
$dest = '/tmp/100MB.bin';
$fp = fopen($dest, 'wb');
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_FILE => $fp, // 直接寫入檔案指標
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 0, // 無超時
CURLOPT_NOPROGRESS => false,
CURLOPT_PROGRESSFUNCTION => function ($ch, $dlTotal, $dlNow) {
if ($dlTotal > 0) {
printf("\rProgress: %.2f%% (%d/%d MB)", $dlNow/$dlTotal*100, $dlNow/1e6, $dlTotal/1e6);
}
},
]);
curl_exec($ch);
curl_close($ch);
fclose($fp);
<?php
// Basic Auth
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// Bearer Token (JWT 等)
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $accessToken,
]);
<?php
curl_setopt($ch, CURLOPT_PROXY, 'https://proxy.example.com:3128');
curl_setopt($ch, CURLOPT_PROXYUSERPWD, 'proxyUser:proxyPass');
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); // 或 SOCKS5
// HTTPS 經 HTTP 代理需 CURLOPT_HTTPPROXYTUNNEL => true
<?php
$urls = [
'https://api1.example.com',
'https://api2.example.com',
'https://api3.example.com',
];
$mh = curl_multi_init();
$handles = [];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_multi_add_handle($mh, $ch);
$handles[$url] = $ch;
}
$running = null;
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh); // 等待活動
} while ($running > 0);
$results = [];
foreach ($handles as $url => $ch) {
$results[$url] = [
'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
'body' => curl_multi_getcontent($ch),
'error' => curl_error($ch),
];
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
CURLOPT_SSL_VERIFYPEER: 生產環境必須驗證憑證;僅測試環境臨時關閉並加註釋。curl_setopt_array: 批量設定更乾淨,避免重複 curl_setopt。=== false: 空字串 "" 也是合法回應,== false 會誤判。curl_getinfo($ch) 回傳關聯陣列,含 http_code、total_time、namelookup_time、connect_time、download_content_length 等,極利於效能分析。CURLOPT_WRITEFUNCTION 可實現流式處理、進度條、多檔案分流。$ch 並用 curl_setopt($ch, CURLOPT_URL, $newUrl) 切換,節省 TCP/SSL 握手開銷。<?php
// 1. 詳細資訊
curl_setopt($ch, CURLOPT_VERBOSE, true);
$verbose = fopen('php://temp', 'rw+');
curl_setopt($ch, CURLOPT_STDERR, $verbose);
// 執行後
rewind($verbose);
echo stream_get_contents($verbose);
// 2. 命令列等效
// curl -v -H "User-Agent: MyApp" "https://api.example.com"
// 3. PHP 內建調試
// php -r 'var_dump(curl_version());'
cURL 是 PHP 與外部世界溝通的瑞士刀。掌握 curl_setopt_array、CURLFile、CURLOPT_WRITEFUNCTION、curl_multi 這幾大核心,配合嚴格錯誤處理與 SSL 驗證,即可構建健壯、高效、可觀測的 HTTP 客戶端。下一步建議學習:Guzzle(物件導向封裝)、Swoole/Workerman 協程 HTTP Client、OpenTelemetry 分散式追蹤整合。